Prexonite, a .NET hosted scripting language with a focus on meta-programming and embedded DSLs
0

Configure Feed

Select the types of activity you want to include in your feed.

PRX-50: Allow more expressions as statements without parentheses

Previously, you'd have to write
```
(asm(ldr.app)).Meta["x"] = ...
```
(put parentheses around `asm(..)`)

The grammar has been refactored a bit to allow the following expressions at the start of a statement without wrapping them in parentheses:

* constant expressions (e.g., `"hello".method();`)
* this expression (e.g., `this.method();`)
* list literal (e.g., `[1, 2].method();`)
* object creation (e.g., `new Object.method();`)
* assembler expressions (e.g., `asm(ldr.app).method();`)

Note: all of these were always allowed within _expressions_ without wrapping them in extra parentheses. This change is solely about using these at the start of a statement.

And yes, some of these (for instance the constant and to some extent the list literal) don't make much sense as the start of a statement, but (A) the _parse_ error message is really difficult to understand and (B) it may then make sense in combination with `>>` or potentially in the future with `=`.

Christian Klauser (Dec 28, 2020, 9:54 PM +0100) 82066c8c bdfeb474

+41 -21
+25 -19
Prexonite/Compiler/Grammar/Parser.Expression.atg
··· 284 284 Primary<out AstExpr expr> 285 285 (. expr = null; 286 286 .) 287 - = 288 - (. _pushLexerState(Lexer.Asm); .) (. var blockExpr = Create.Block(GetPosition()); 289 - _PushScope(blockExpr); 290 - .) 291 - asm lpar { AsmInstruction<blockExpr> } rpar 292 - (. _popLexerState(); .) (. expr = blockExpr; 293 - _PopScope(blockExpr); 294 - .) 295 - | Constant<out expr> 296 - | ThisExpression<out expr> 297 - | CoroutineCreation<out expr> 298 - | ListLiteral<out expr> 287 + = IF(isLambdaExpression()) 288 + LambdaExpression<out expr> 289 + | lpar Expr<out expr> rpar 299 290 | HashLiteral<out expr> 291 + | CoroutineCreation<out expr> 300 292 | LoopExpr<out expr> 301 - | (. AstThrow th; .) 302 - ThrowExpression<out th> (. expr = th; .) 303 - | IF(isLambdaExpression()) 304 - LambdaExpression<out expr> 293 + | ThrowExpression<out var th> (. expr = th; .) 305 294 | LazyExpression<out expr> 306 - | lpar Expr<out expr> rpar 307 - | IF(_isNotNewDecl()) ObjectCreation<out expr> 308 - | GetInitiator<out expr> 295 + | PrimaryForGetSetComplex<out expr> 309 296 | LPopExpr lpar Expr<out expr> (. //This is a hack that makes string interpolation with expressions possible 310 297 //The non-verbal token "LPopExpr" (has no character representation) is 311 298 //returned by the lexer if the parser has to treat an expression in a special ··· 313 300 //well as injecting the necessary plus operator. 314 301 _popLexerState(); _inject(_plus); .) 315 302 rpar 303 + . 304 + 305 + // These are primary expressions that are suitable to use as the LHS of `LHS.method(call)` or `LHS[index]`. 306 + PrimaryForGetSetComplex<out AstExpr expr> 307 + (. expr = null; .) 308 + = Constant<out expr> 309 + | ThisExpression<out expr> 310 + // Note: the HashLiteral *cannot* appear here. A statement cannot start with an `{` because then it cannot be 311 + // distinguished from a block. 312 + | ListLiteral<out expr> 313 + | IF(_isNotNewDecl()) ObjectCreation<out expr> 314 + | (. _pushLexerState(Lexer.Asm); .) (. var blockExpr = Create.Block(GetPosition()); 315 + _PushScope(blockExpr); 316 + .) 317 + asm lpar { AsmInstruction<blockExpr> } rpar 318 + (. _popLexerState(); .) (. expr = blockExpr; 319 + _PopScope(blockExpr); 320 + .) 321 + | GetInitiator<out expr> 316 322 . 317 323 318 324 Constant<out AstExpr expr>
+3 -2
Prexonite/Compiler/Grammar/Parser.Statement.atg
··· 29 29 Statement<AstBlock block> 30 30 = 31 31 ( IF( isLabel() ) 32 - ExplicitLabel<block> 32 + ExplicitLabel<block> 33 + | IF( isAsmBlock() ) StructureStatement<block> 33 34 | [ SimpleStatement<block> ] semicolon 34 35 | StructureStatement<block> 35 36 ) ··· 73 74 .) 74 75 = 75 76 //GetSet Initiator 76 - GetInitiator<out expr> (. complex = expr as AstGetSet; .) 77 + PrimaryForGetSetComplex<out expr> (. complex = expr as AstGetSet; .) 77 78 78 79 //GetSet Extensions 79 80 { GetSetExtension<expr, out complex> (. expr = complex; .)
+13
Prexonite/Compiler/Parser.Code.cs
··· 834 834 return c.kind == _dot && cla.kind == _lpar; 835 835 } 836 836 837 + // used to distinguish asm{...} and asm(...) 838 + private bool isAsmBlock() //LL(2) 839 + { 840 + var asm = la; 841 + if (asm.kind != _asm) 842 + { 843 + return false; 844 + } 845 + 846 + scanner.ResetPeek(); 847 + return scanner.Peek().kind == _lbrace; 848 + } 849 + 837 850 [DebuggerStepThrough] 838 851 private bool isOuterVariable(string id) //context 839 852 {