Index: src/Boo.Lang.Parser/boo.g =================================================================== --- src/Boo.Lang.Parser/boo.g (revision 2088) +++ src/Boo.Lang.Parser/boo.g (working copy) @@ -52,6 +52,7 @@ ELIST; // expression list DLIST; // declaration list ESEPARATOR; // expression separator (imaginary token) + EOL; ABSTRACT="abstract"; AND="and"; AS="as"; @@ -312,9 +313,9 @@ cu.Modules.Add(module); }: - (options { greedy=true;}: EOS)* + (eos)? docstring[module] - (options { greedy=true;}: EOS)* + (eos)? (namespace_directive[module])? (import_directive[module])* (type_member[module.Members])* @@ -326,12 +327,12 @@ protected docstring[Node node]: ( doc:TRIPLE_QUOTED_STRING { node.Documentation = MassageDocString(doc.getText()); } - (options { greedy=true; }: EOS)* + (eos)? )? ; protected -eos : (options { greedy = true; }: EOS)+; +eos : (options { greedy = true; }: (EOL|EOS))+; protected import_directive[Module container] @@ -481,7 +482,7 @@ )* )? RBRACK - (EOS)* + (eos)? )* ; @@ -546,7 +547,7 @@ ( (PASS eos) | ( - (EOS)* + (eos)? (type_definition_member[members])+ ) ) @@ -626,7 +627,7 @@ LPAREN parameter_declaration_list[m.Parameters] RPAREN (AS rt=type_reference { m.ReturnType=rt; })? ( - (eos docstring[m]) | (empty_block[m] (EOS)*) + (eos docstring[m]) | (empty_block[m] (eos)?) ) ; @@ -910,13 +911,13 @@ protected globals[Module container]: - (EOS)* + (eos)? (stmt[container.Globals.Statements])* ; protected block[StatementCollection container]: - (EOS)* + (eos)? ( (PASS eos) | ( @@ -1145,11 +1146,11 @@ begin: COLON INDENT; protected -begin_with_doc[Node node]: COLON (EOS docstring[node])? INDENT; +begin_with_doc[Node node]: COLON (eos docstring[node])? INDENT; protected begin_block_with_doc[Node node, Block block]: - COLON (EOS docstring[node])? + COLON (eos docstring[node])? begin:INDENT { block.LexicalInfo = ToLexicalInfo(begin); @@ -1159,23 +1160,30 @@ protected end[Node node] : t:DEDENT { node.EndSourceLocation = ToSourceLocation(t); } - (options { greedy=true; }: EOS)* + (eos)? ; protected compound_stmt[Block b] { - StatementCollection statements = null; + StatementCollection statements = b.Statements; }: - COLON begin:INDENT - { - b.LexicalInfo = ToLexicalInfo(begin); - statements = b.Statements; - } + ( + COLON + simple_stmt[statements] + (options { greedy = true; }: EOS (simple_stmt[statements])?)* + (options { greedy = true; }: EOL)+ + ) | + ( + COLON begin:INDENT + { + b.LexicalInfo = ToLexicalInfo(begin); + } block[statements] - end[b] + end[b] + ) ; - + protected closure_macro_stmt returns [MacroStatement returnValue] { @@ -1213,6 +1221,21 @@ ; protected +simple_macro_stmt returns [MacroStatement returnValue] + { + returnValue = null; + MacroStatement macro = new MacroStatement(); + }: + id:ID expression_list[macro.Arguments] + { + macro.Name = id.getText(); + macro.LexicalInfo = ToLexicalInfo(id); + + returnValue = macro; + } +; + +protected goto_stmt returns [GotoStatement stmt] { stmt = null; @@ -1279,6 +1302,38 @@ ; protected +simple_stmt [StatementCollection container] + { + Statement s = null; + }: + ( + (ID (expression)?)=>{IsValidMacroArgument(LA(2))}? s=simple_macro_stmt | + (slicing_expression (ASSIGN|(DO|DEF)))=> s=assignment_or_method_invocation_with_block_stmt | + s=return_stmt | + (declaration COMMA)=> s=unpack_stmt | + s=declaration_stmt | + ( + ( + s=goto_stmt | + s=label_stmt | + s=yield_stmt | + s=break_stmt | + s=continue_stmt | + s=raise_stmt | + s=retry_stmt | + s=expression_stmt + ) + ) + ) + { + if (null != s) + { + container.Add(s); + } + } + ; + +protected stmt_modifier returns [StatementModifier m] { m = null; @@ -3110,7 +3165,7 @@ "*/" { $setType(Token.SKIP); } ; - + WS : ( ' ' | @@ -3125,7 +3180,7 @@ } } ; - + EOS: ';'; X_RE_LITERAL: '@'!'/' (X_RE_CHAR)+ '/' { $setType(RE_LITERAL); }; Index: src/Boo.Lang.Parser/BooParser.cs =================================================================== --- src/Boo.Lang.Parser/BooParser.cs (revision 2051) +++ src/Boo.Lang.Parser/BooParser.cs (working copy) @@ -114,7 +114,7 @@ lexer.setFilename(readerName); lexer.Initialize(selector, tabSize, BooToken.TokenCreator); - IndentTokenStreamFilter filter = new IndentTokenStreamFilter(lexer, WS, INDENT, DEDENT, EOS); + IndentTokenStreamFilter filter = new IndentTokenStreamFilter(lexer, WS, INDENT, DEDENT, EOL); selector.select(filter); return selector; Index: src/Boo.Lang.Parser/Util/IndentTokenStreamFilter.cs =================================================================== --- src/Boo.Lang.Parser/Util/IndentTokenStreamFilter.cs (revision 2051) +++ src/Boo.Lang.Parser/Util/IndentTokenStreamFilter.cs (working copy) @@ -201,7 +201,7 @@ void EnqueueEOS(antlr.IToken originalToken) { - _pendingTokens.Enqueue(CreateToken(originalToken, _eosTokenType, "")); + _pendingTokens.Enqueue(CreateToken(originalToken, _eosTokenType, "")); } antlr.IToken CreateToken(antlr.IToken originalToken, int newTokenType, string newTokenText) Index: tests/testcases/compilation/simple_statements.boo =================================================================== --- tests/testcases/compilation/simple_statements.boo (revision 0) +++ tests/testcases/compilation/simple_statements.boo (revision 0) @@ -0,0 +1,37 @@ +""" +0 +1 +2 3 +9 +90 +900 +false +caught it +yessir +""" + +if true: print(0) +if true: print 1 +if true: print 2, 3 + +//test multiple method invocations on one line: +if false: print(6);print(7);print(8); //none should be printed +print(9); //should be printed + +//test multiple macros on one line: +if false: print 60; print 70; print 80 //none should be printed +print 90 //should be printed + +//test mix: +if false: print 600; print(700); print 800; //none should be printed +print(900) //should be printed + +if false: print "true" +else: print "false" + +try: raise "uh oh" +except e: print "caught it"; print "yessir" + +//if true: if true: //not allowed +// print "ok" +