Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • S sweet-core
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 62
    • Issues 62
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 4
    • Merge requests 4
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • sweet-js
  • sweet-core
  • Wiki
  • design

design · Changes

Page history
updating the reader authored Aug 06, 2013 by Tim Disney's avatar Tim Disney
Show whitespace changes
Inline Side-by-side
design.md
View page @ d1660008
# Preliminary Design # Preliminary Design
(note: some of this is already outdated, will revise)
## Reading ## Reading
To do macros we need to `read`. To `read` we need to match delimiters To do macros we need to `read`. To `read` we need to match delimiters
...@@ -19,27 +17,73 @@ disambiguate. Algorithm: ...@@ -19,27 +17,73 @@ disambiguate. Algorithm:
skip over comments skip over comments
if tok is / if tok is /
if tok-1 is ) if tok-1 is ()
look back to matching ( if tok-2 in "if" "while" "for" "with"
if identifier before ( in "if" "while" "for" "with"
tok is start of regex literal tok is start of regex literal
else else
tok is divide tok is divide
if tok-1 is } else if tok-1 is {}
if end of function expression // described below if isBlock(tok-1)
tok is start of divide // named or anonymous function
if tok-2 is () and tok-3 is "function" or tok-4 is "function"
if function expression // how to determine is described below
tok is divide
else else
tok is start of regex literal tok is start of regex literal
else
if tok-1 in punctuator // e.g. ";", "==", ">", "/", "+", etc.
tok is start of regex literal tok is start of regex literal
else
if tok-1 in keywords // though some keywords will eventually result in a parse error tok is divide
else if tok-1 in punctuator // e.g. ";", "==", ">", "/", "+", etc.
tok is start of regex literal
else if tok-1 in keywords
// though some keywords will eventually result in a parse error (eg. debugger, break)
tok is start of regex literal tok is start of regex literal
else else
tok is divide tok is divide
assignOps = ["=", "+=", "-=", "*=", "/=", "%=",
"<<=", ">>=", ">>>=", "&=", "|=", "^=", ","];
binaryOps = ["+", "-", "*", "/", "%","<<", ">>", ">>>",
"&", "|", "^","&&", "||", "?", ":",
"instanceof"
"===", "==", ">=", "<=", "<", ">", "!=", "!=="];
unaryOps = ["++", "--", "~", "!", "delete", "void", "typeof", "throw", "new"];
function isBlock(tok)
if tok-1 is ( or [
// ... ({...} ...)
return false
else if tok-1 is ":" and parent token is {}
// ... {a:{...} ...}
return isBlock(the parent {})
else if tok-1 is one of assignOps unaryOps binaryOps
// ... + {...}
// ... typeof {...}
return false
else if tok-1 is "return"
// handle ASI
if lineNumber(tok) isnt lineNumber(tok-1)
// return
// {...}
return true
else
// return {...}
return false
else if tok-1 is "yield" // could also put "yield" in unaryOps
return false
else if tok-1 is one of "debugger" "break" "continue" "throw"
parse error
else if tok-1 is one of "void" "typeof" "in" "case" "delete"
// ... in {...}
return false
else
return true
Depending on context, `function name() {}` is either a function declaration or a Depending on context, `function name() {}` is either a function declaration or a
function expression. If it's a function expression then function expression. If it's a function expression then
a following `/` will be interpreted as a divide but if it's a a following `/` will be interpreted as a divide but if it's a
...@@ -58,9 +102,9 @@ following imply it is a function declaration: ...@@ -58,9 +102,9 @@ following imply it is a function declaration:
; } ) ] ident literal (including regex literal so need to be careful about /) ; } ) ] ident literal (including regex literal so need to be careful about /)
debugger break continue else debugger break continue else
And these imply it is an function expression. And these imply it is a function expression.
( { [ , (assignment operators) (binary operators) (unary operators) ( [ , (assignment operators) (binary operators) (unary operators)
in typeof instanceof new return case delete in typeof instanceof new return case delete
throw void throw void
...@@ -139,45 +183,6 @@ etc.) as really reserved. Macros can't override their meaning. ...@@ -139,45 +183,6 @@ etc.) as really reserved. Macros can't override their meaning.
Should we disallow FutureReservedWords too (`class`, `enum`, etc.)? Should we disallow FutureReservedWords too (`class`, `enum`, etc.)?
## Scope
Macro definitions should be scoped appropriately.
What should we do about hoisting? For example,
macro foo { ... }
function bar() {
foo(...)
if (x) {
var foo = function () { ... }
foo(...)
} else {
var foo = function () { ... }
}
}
Because of hoisting, the variable `foo` will shadow the macro definition of
`foo` in this code. But this is complex and annoying. Can we just say
that hoisting always happens after macro expansion? So the first
`foo(...)` is a macro invocation and the second `foo(...)` is a
function call? Does this cause any problems?
So I think we have to have hoisting happen after macro expansion. But what does this mean for hygiene?
macro foo { ... }
foo { bar = 4 }
var bar = 5;
## Hygiene
Should be [fun](http://www.quotationspage.com/quote/26964.html)...
## Modules
Details about importing macros from another module...
## Example Code ## Example Code
...@@ -445,25 +450,10 @@ These names aren't quite right. What is JavaScripty? ...@@ -445,25 +450,10 @@ These names aren't quite right. What is JavaScripty?
} }
} }
## Misc
* sub-form expansion? MTWT says parse and expand must be separate to do sub-form expansion.
## potential macros
heredoc or multi line strings.
s = heredoc {this is a nice
multiline string
that keeps spaces
the only problem is it can't break tokenization...
}
string templates
## Papers ## Papers
Papers I've been looking through: Useful papers on macros:
* Macros that work * Macros that work
* Macros that work together * Macros that work together
...@@ -476,6 +466,3 @@ Papers I've been looking through: ...@@ -476,6 +466,3 @@ Papers I've been looking through:
* Fortifying Macros * Fortifying Macros
* Composable and Compilable Macros * Composable and Compilable Macros
What others might be helpful?
Clone repository
  • Example macros
  • FAQ
  • High level design overview
  • Home
  • Macro resources
  • Patterns
  • Syntax Case
  • case api
  • custom operators
  • design
  • expander design
  • modules
  • node loader
  • pattern_class
  • reader scratch
View All Pages