Added Statement to the grammar.

This commit is contained in:
Tim Jones
2010-04-06 02:26:23 +12:00
parent 19ed63129e
commit de955dacc4
3 changed files with 260 additions and 213 deletions

View File

@@ -53,25 +53,33 @@
return new Expressions(); return new Expressions();
}), o("TERMINATOR", function() { }), o("TERMINATOR", function() {
return new Expressions(); return new Expressions();
}), o("Expressions"), o("Block TERMINATOR") }), o("Body"), o("Block TERMINATOR")
], ],
// Any list of expressions or method body, seperated by line breaks or // Any list of statements and expressions, seperated by line breaks or semicolons.
// semicolons. Body: [o("Line", function() {
Expressions: [o("Expression", function() {
return Expressions.wrap([$1]); return Expressions.wrap([$1]);
}), o("Expressions TERMINATOR Expression", function() { }), o("Body TERMINATOR Line", function() {
return $1.push($3); return $1.push($3);
}), o("Expressions TERMINATOR") }), o("Body TERMINATOR")
],
// Expressions and statements, which make up a line in a body.
Line: [o("Expression"), o("Statement")],
// Pure statements which cannot be expressions.
Statement: [o("Return"), o("Throw"), o("BREAK", function() {
return new LiteralNode(yytext);
}), o("CONTINUE", function() {
return new LiteralNode(yytext);
})
], ],
// All the different types of expressions in our language. The basic unit of // All the different types of expressions in our language. The basic unit of
// CoffeeScript is the **Expression** -- you'll notice that there is no // CoffeeScript is the **Expression** -- everything that can be an expression
// "statement" nonterminal. Expressions serve as the building blocks // is one. Expressions serve as the building blocks of many other rules, making
// of many other rules, making them somewhat circular. // them somewhat circular.
Expression: [o("Value"), o("Call"), o("Curry"), o("Code"), o("Operation"), o("Assign"), o("If"), o("Try"), o("Throw"), o("Return"), o("While"), o("For"), o("Switch"), o("Extends"), o("Class"), o("Splat"), o("Existence"), o("Comment"), o("Extension")], Expression: [o("Value"), o("Call"), o("Curry"), o("Code"), o("Operation"), o("Assign"), o("If"), o("Try"), o("While"), o("For"), o("Switch"), o("Extends"), o("Class"), o("Splat"), o("Existence"), o("Comment"), o("Extension")],
// A an indented block of expressions. Note that the [Rewriter](rewriter.html) // A an indented block of expressions. Note that the [Rewriter](rewriter.html)
// will convert some postfix forms into blocks for us, by adjusting the // will convert some postfix forms into blocks for us, by adjusting the
// token stream. // token stream.
Block: [o("INDENT Expressions OUTDENT", function() { Block: [o("INDENT Body OUTDENT", function() {
return $2; return $2;
}), o("INDENT OUTDENT", function() { }), o("INDENT OUTDENT", function() {
return new Expressions(); return new Expressions();
@@ -98,10 +106,6 @@
return new LiteralNode(yytext); return new LiteralNode(yytext);
}), o("REGEX", function() { }), o("REGEX", function() {
return new LiteralNode(yytext); return new LiteralNode(yytext);
}), o("BREAK", function() {
return new LiteralNode(yytext);
}), o("CONTINUE", function() {
return new LiteralNode(yytext);
}), o("TRUE", function() { }), o("TRUE", function() {
return new LiteralNode(true); return new LiteralNode(true);
}), o("FALSE", function() { }), o("FALSE", function() {
@@ -420,7 +424,7 @@
// not an **Expression**, so if you need to use an expression in a place // not an **Expression**, so if you need to use an expression in a place
// where only values are accepted, wrapping it in parentheses will always do // where only values are accepted, wrapping it in parentheses will always do
// the trick. // the trick.
Parenthetical: [o("( Expression )", function() { Parenthetical: [o("( Line )", function() {
return new ParentheticalNode($2); return new ParentheticalNode($2);
}) })
], ],
@@ -443,6 +447,8 @@
// or postfix, with a single expression. There is no do..while. // or postfix, with a single expression. There is no do..while.
While: [o("WhileSource Block", function() { While: [o("WhileSource Block", function() {
return $1.add_body($2); return $1.add_body($2);
}), o("Statement WhileSource", function() {
return $2.add_body(Expressions.wrap([$1]));
}), o("Expression WhileSource", function() { }), o("Expression WhileSource", function() {
return $2.add_body(Expressions.wrap([$1])); return $2.add_body(Expressions.wrap([$1]));
}) })
@@ -450,7 +456,9 @@
// Array, object, and range comprehensions, at the most generic level. // Array, object, and range comprehensions, at the most generic level.
// Comprehensions can either be normal, with a block of expressions to execute, // Comprehensions can either be normal, with a block of expressions to execute,
// or postfix, with a single expression. // or postfix, with a single expression.
For: [o("Expression FOR ForVariables ForSource", function() { For: [o("Statement FOR ForVariables ForSource", function() {
return new ForNode($1, $4, $3[0], $3[1]);
}), o("Expression FOR ForVariables ForSource", function() {
return new ForNode($1, $4, $3[0], $3[1]); return new ForNode($1, $4, $3[0], $3[1]);
}), o("FOR ForVariables ForSource Block", function() { }), o("FOR ForVariables ForSource Block", function() {
return new ForNode($4, $3, $2[0], $2[1]); return new ForNode($4, $3, $2[0], $2[1]);
@@ -556,10 +564,19 @@
], ],
// The full complement of *if* expressions, including postfix one-liner // The full complement of *if* expressions, including postfix one-liner
// *if* and *unless*. // *if* and *unless*.
If: [o("IfBlock"), o("Expression IF Expression", function() { If: [o("IfBlock"), o("Statement IF Expression", function() {
return new IfNode($3, Expressions.wrap([$1]), null, { return new IfNode($3, Expressions.wrap([$1]), null, {
statement: true statement: true
}); });
}), o("Expression IF Expression", function() {
return new IfNode($3, Expressions.wrap([$1]), null, {
statement: true
});
}), o("Statement UNLESS Expression", function() {
return new IfNode($3, Expressions.wrap([$1]), null, {
statement: true,
invert: true
});
}), o("Expression UNLESS Expression", function() { }), o("Expression UNLESS Expression", function() {
return new IfNode($3, Expressions.wrap([$1]), null, { return new IfNode($3, Expressions.wrap([$1]), null, {
statement: true, statement: true,

File diff suppressed because one or more lines are too long

View File

@@ -55,22 +55,35 @@ grammar: {
Root: [ Root: [
o "", -> new Expressions() o "", -> new Expressions()
o "TERMINATOR", -> new Expressions() o "TERMINATOR", -> new Expressions()
o "Expressions" o "Body"
o "Block TERMINATOR" o "Block TERMINATOR"
] ]
# Any list of expressions or method body, seperated by line breaks or # Any list of statements and expressions, seperated by line breaks or semicolons.
# semicolons. Body: [
Expressions: [ o "Line", -> Expressions.wrap [$1]
o "Expression", -> Expressions.wrap [$1] o "Body TERMINATOR Line", -> $1.push $3
o "Expressions TERMINATOR Expression", -> $1.push $3 o "Body TERMINATOR"
o "Expressions TERMINATOR" ]
# Expressions and statements, which make up a line in a body.
Line: [
o "Expression"
o "Statement"
]
# Pure statements which cannot be expressions.
Statement: [
o "Return"
o "Throw"
o "BREAK", -> new LiteralNode yytext
o "CONTINUE", -> new LiteralNode yytext
] ]
# All the different types of expressions in our language. The basic unit of # All the different types of expressions in our language. The basic unit of
# CoffeeScript is the **Expression** -- you'll notice that there is no # CoffeeScript is the **Expression** -- everything that can be an expression
# "statement" nonterminal. Expressions serve as the building blocks # is one. Expressions serve as the building blocks of many other rules, making
# of many other rules, making them somewhat circular. # them somewhat circular.
Expression: [ Expression: [
o "Value" o "Value"
o "Call" o "Call"
@@ -80,8 +93,6 @@ grammar: {
o "Assign" o "Assign"
o "If" o "If"
o "Try" o "Try"
o "Throw"
o "Return"
o "While" o "While"
o "For" o "For"
o "Switch" o "Switch"
@@ -97,7 +108,7 @@ grammar: {
# will convert some postfix forms into blocks for us, by adjusting the # will convert some postfix forms into blocks for us, by adjusting the
# token stream. # token stream.
Block: [ Block: [
o "INDENT Expressions OUTDENT", -> $2 o "INDENT Body OUTDENT", -> $2
o "INDENT OUTDENT", -> new Expressions() o "INDENT OUTDENT", -> new Expressions()
o "TERMINATOR Comment", -> Expressions.wrap [$2] o "TERMINATOR Comment", -> Expressions.wrap [$2]
] ]
@@ -120,8 +131,6 @@ grammar: {
o "AlphaNumeric" o "AlphaNumeric"
o "JS", -> new LiteralNode yytext o "JS", -> new LiteralNode yytext
o "REGEX", -> new LiteralNode yytext o "REGEX", -> new LiteralNode yytext
o "BREAK", -> new LiteralNode yytext
o "CONTINUE", -> new LiteralNode yytext
o "TRUE", -> new LiteralNode true o "TRUE", -> new LiteralNode true
o "FALSE", -> new LiteralNode false o "FALSE", -> new LiteralNode false
o "YES", -> new LiteralNode true o "YES", -> new LiteralNode true
@@ -396,7 +405,7 @@ grammar: {
# where only values are accepted, wrapping it in parentheses will always do # where only values are accepted, wrapping it in parentheses will always do
# the trick. # the trick.
Parenthetical: [ Parenthetical: [
o "( Expression )", -> new ParentheticalNode $2 o "( Line )", -> new ParentheticalNode $2
] ]
# A language extension to CoffeeScript from the outside. We simply pass # A language extension to CoffeeScript from the outside. We simply pass
@@ -415,6 +424,7 @@ grammar: {
# or postfix, with a single expression. There is no do..while. # or postfix, with a single expression. There is no do..while.
While: [ While: [
o "WhileSource Block", -> $1.add_body $2 o "WhileSource Block", -> $1.add_body $2
o "Statement WhileSource", -> $2.add_body Expressions.wrap [$1]
o "Expression WhileSource", -> $2.add_body Expressions.wrap [$1] o "Expression WhileSource", -> $2.add_body Expressions.wrap [$1]
] ]
@@ -422,6 +432,7 @@ grammar: {
# Comprehensions can either be normal, with a block of expressions to execute, # Comprehensions can either be normal, with a block of expressions to execute,
# or postfix, with a single expression. # or postfix, with a single expression.
For: [ For: [
o "Statement FOR ForVariables ForSource", -> new ForNode $1, $4, $3[0], $3[1]
o "Expression FOR ForVariables ForSource", -> new ForNode $1, $4, $3[0], $3[1] o "Expression FOR ForVariables ForSource", -> new ForNode $1, $4, $3[0], $3[1]
o "FOR ForVariables ForSource Block", -> new ForNode $4, $3, $2[0], $2[1] o "FOR ForVariables ForSource Block", -> new ForNode $4, $3, $2[0], $2[1]
] ]
@@ -491,7 +502,9 @@ grammar: {
# *if* and *unless*. # *if* and *unless*.
If: [ If: [
o "IfBlock" o "IfBlock"
o "Statement IF Expression", -> new IfNode $3, Expressions.wrap([$1]), null, {statement: true}
o "Expression IF Expression", -> new IfNode $3, Expressions.wrap([$1]), null, {statement: true} o "Expression IF Expression", -> new IfNode $3, Expressions.wrap([$1]), null, {statement: true}
o "Statement UNLESS Expression", -> new IfNode $3, Expressions.wrap([$1]), null, {statement: true, invert: true}
o "Expression UNLESS Expression", -> new IfNode $3, Expressions.wrap([$1]), null, {statement: true, invert: true} o "Expression UNLESS Expression", -> new IfNode $3, Expressions.wrap([$1]), null, {statement: true, invert: true}
] ]