Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Squirrel grammar #237

Open
mingodad opened this issue May 20, 2021 · 7 comments
Open

Squirrel grammar #237

mingodad opened this issue May 20, 2021 · 7 comments

Comments

@mingodad
Copy link
Contributor

mingodad commented May 20, 2021

I'm testing this interesting parser generator https://ssw.jku.at/Research/Projects/Coco/ and as exercise I'm building a Squirrel/SquiLu grammar with it.

As usual any feedback is welcome !

This is the initial CocoR grammar just in case someone else want to try (edited with my latest):


#include "Scanner.nut"

COMPILER Squirrel

CHARACTERS
	letter    = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_".
	oct        = '0'..'7'.
	digit     = '0'..'9'.
	nzdigit    = '1'..'9'.
	cr        = '\r'.
	lf        = '\n'.
	tab       = '\t'.
	stringCh  = ANY - '"' - '\\' - cr - lf.
	charCh    = ANY - '\'' - '\\' - cr - lf.
	printable = '\u0020' .. '\u007e'.
	hex        = digit + 'a'..'f' + 'A'..'F'.

TOKENS
	TK_IDENTIFIER     = letter { letter | digit }.

	TK_FLOAT = ( '.' digit {digit} [('e'|'E')  ['+'|'-'] digit {digit}]
						 | digit {digit} '.' {digit} [('e'|'E')  ['+'|'-'] digit {digit}]
						 | digit {digit} ('e'|'E')  ['+'|'-'] digit {digit}
						 )
						 .

	TK_INTEGER   = ( /*nz*/ digit {digit}
						 //| '0' {oct}
						 | ("0x"|"0X") hex {hex}
						 )
						 .

	TK_STRING_LITERAL    = ['@'] '"' {stringCh |  '\\' (printable | ['\r'] '\n')} '"'
			| "'" { charCh | '\\' (printable | ['\r'] '\n')} "'"
			.

	badString = '"' {stringCh | '\\' printable} (cr | lf)
			| "'" {charCh | '\\' printable } (cr | lf)
			.

	TK_AND = "&&".
	TK_ATTR_CLOSE = "/>".
	TK_ATTR_OPEN = "</".
	TK_BASE = "base".
	TK_BIT_AND_EQ = "&=".
	TK_BIT_OR_EQ = "|=".
	TK_BIT_SHIFT_LEFT_EQ = "<<=".
	TK_BIT_SHIFT_RIGHT_EQ = ">>=".
	TK_BIT_XOR_EQ = "^=".
	TK_BREAK = "break".
	TK_CASE = "case".
	TK_CATCH = "catch".
	TK_CLASS = "class".
	TK_CLONE = "clone".
	TK_CONST = "const".
	TK_CONTINUE = "continue".
	TK_CONSTRUCTOR = "constructor".
	TK_DEFAULT = "default".
	TK_DELETE = "delete".
	TK_DIVEQ = "/=".
	TK_DO = "do".
	TK_DOUBLE_COLON = "::".
	TK_EQ = "==".
	TK_ELSE = "else".
	TK_ENUM = "enum".
	TK_FALSE = "false".
	TK___FILE__ = "__FILE__".
	TK_FOREACH = "foreach".
	TK_FOR = "for".
	TK_FUNCTION = "function".
	TK___FUNCTION__ = "__FUNCTION__".
	TK_GOTO = "goto".
	TK_GE = ">=".
	TK_IF = "if".
	TK_IN = "in".
	TK_INSTANCEOF = "instanceof".
	TK_LE = "<=".
	TK___LINE__ = "__LINE__".
	TK_LOCAL = "local".
	TK_MINUSEQ = "-=".
	TK_MINUSMINUS = "--".
	TK_MODEQ = "%=".
	TK_MULEQ = "*=".
	TK_NE = "!=".
	TK_NEWSLOT = "<-".
	TK_NULL = "null".
	TK_OR = "||".
	TK_PLUSEQ = "+=".
	TK_PLUSPLUS = "++".
	TK_RAWCALL = "rawcall".
	TK_RESUME = "resume".
	TK_RETURN = "return".
	TK_SHIFTL = ">>".
	TK_SHIFTR = "<<".
	TK_STATIC = "static".
	TK_SWITCH = "switch".
	TK_THIS = "this".
	TK_THROW = "throw".
	TK_3WAYSCMP = "<=>".
	TK_TRUE = "true".
	TK_TRY = "try".
	TK_TYPEOF = "typeof".
	TK_USHIFTR = ">>>".
	TK_VARPARAMS = "...".
	TK_WHILE = "while".
	TK_YIELD = "yield".




COMMENTS FROM "/*" TO "*/" NESTED
COMMENTS FROM "//" TO lf

IGNORE cr + lf + tab

PRODUCTIONS

Squirrel = {Statement}
	.

Statement =
	(
	IfStatement
	| WhileStatement
	| DoWhileStatement
	| ForStatement
	| ForEachStatement
	| SwitchStatement
	| LocalDeclStatement
	| ReturnStatement
	| YeldStatement
	| BreakStatement
	| ContinueStatement
	| FunctionStatement
	| ClassStatement
	| EnumStatement
	| Statements
	| TryCatchStatement
	| ThrowStatement
	| ConstStatement
	| CommaExpr
	) [';']
	.

IfStatement = TK_IF '(' CommaExpr ')' IfBlock [TK_ELSE IfBlock]
	.

IfBlock = Statement
	.

WhileStatement = TK_WHILE '(' CommaExpr ')' Statement
	.

DoWhileStatement = TK_DO Statement TK_WHILE '(' CommaExpr ')'
	.

ForStatement = TK_FOR '(' [LocalDeclStatement | CommaExpr] ';' [CommaExpr] ';' [CommaExpr] ')' Statement
	.

ForEachStatement = TK_FOREACH '(' TK_IDENTIFIER [',' TK_IDENTIFIER] TK_IN Expression ')' Statement
	.

SwitchStatement = TK_SWITCH '(' CommaExpr ')'  '{' {CaseStatement} [TK_DEFAULT ':' Statement] '}'
	.

CaseStatement = TK_CASE ExpressionScalar ':' [Statement]
	.

LocalDeclStatement = TK_LOCAL
	(
	TK_FUNCTION TK_IDENTIFIER CreateFunction
	|  AssignExpr {',' AssignExpr}
	)
	.

AssignExpr = TK_IDENTIFIER ['=' Expression]
	.

ReturnStatement = TK_RETURN [CommaExpr]
	.

YeldStatement = TK_YIELD [CommaExpr]
	.

BreakStatement = TK_BREAK
	.

ContinueStatement = TK_CONTINUE
	.

FunctionStatement = TK_FUNCTION TK_IDENTIFIER {"::" (TK_IDENTIFIER | TK_CONSTRUCTOR)} CreateFunction
	.

CreateFunction =  FunctionParams Statement
	.

CreateLambda =  FunctionParams Expression
	.

FunctionParams =  '(' [TK_VARPARAMS | OneFunctionParam {',' OneFunctionParam}] ')'
	.

OneFunctionParam =  TK_IDENTIFIER ['=' Expression]
	.

ClassStatement =
	TK_CLASS PrefixedExpr
	(';' | ClassExp)
	.

ClassExp = ["extends" Expression]
		[TK_ATTR_OPEN {ParseTable} TK_ATTR_CLOSE]
		'{' {ParseClass} '}'
	.

ParseClass = ParseTableOrClass [';']
	.

ParseTable = ParseTableOrClass [',']
	.

ParseTableOrClass =
	([TK_STATIC] TK_FUNCTION TK_IDENTIFIER | TK_CONSTRUCTOR) CreateFunction
	| '[' CommaExpr ']' '=' Expression
	| TK_STRING_LITERAL ':' Expression
	| TK_IDENTIFIER '=' Expression
	.

EnumStatement = TK_ENUM TK_IDENTIFIER '{' EnumItem {',' EnumItem} '}'
	.

EnumItem = TK_IDENTIFIER ['=' ExpectScalar]
	.

Statements = '{' {Statement} '}'
	.

TryCatchStatement = TK_TRY Statement TK_CATCH '(' TK_IDENTIFIER ')' Statement
	.

ThrowStatement = TK_THROW CommaExpr
	.

ConstStatement = TK_CONST (TK_IDENTIFIER '=' ExpectScalar)
	.

ExpectScalar = (['-'] (TK_INTEGER | TK_FLOAT)) | TK_STRING_LITERAL | TK_TRUE | TK_FALSE
	.

CommaExpr = Expression {',' Expression}
	.

Expression =
	LogicalOrExp [
		('=' | TK_NEWSLOT | TK_MINUSEQ | TK_PLUSEQ | TK_MULEQ | TK_DIVEQ | TK_MODEQ) Expression
		| '?' Expression ':' Expression
	]
	.

LogicalOrExp = LogicalAndExp {TK_OR LogicalOrExp}
	.

LogicalAndExp = BitwiseOrExp {TK_AND LogicalAndExp}
	.

BitwiseOrExp = BitwiseXorExp {'|' BitwiseXorExp}
	.

BitwiseXorExp = BitwiseAndExp {'^' BitwiseAndExp}
	.

BitwiseAndExp = EqExp {'&' EqExp}
	.

EqExp = CompExp {(TK_EQ | TK_NE | TK_3WAYSCMP) CompExp}
	.

CompExp = ShiftExp {('>' | '<' | TK_GE | TK_LE | TK_IN | TK_INSTANCEOF) ShiftExp}
	.

ShiftExp = PlusExp {(TK_USHIFTR | TK_SHIFTL | TK_SHIFTR) PlusExp}
	.

PlusExp = MultExp {('+' | '-') MultExp}
	.

MultExp = PrefixedExpr {('*' | '/' | '%') PrefixedExpr}
	.

PrefixedExpr = Factor
	{
		'.' (TK_IDENTIFIER | TK_CONSTRUCTOR)
		| '[' Expression ']'
		| (TK_MINUSMINUS | TK_PLUSPLUS)
		| FunctionCallArgs
	}
	.

Factor =
	TK_STRING_LITERAL
	| TK_BASE
	| TK_IDENTIFIER
	| TK_CONSTRUCTOR
	| TK_THIS
	| TK_DOUBLE_COLON PrefixedExpr
	| TK_NULL
	| TK_INTEGER
	| TK_FLOAT
	| TK_TRUE
	| TK_FALSE
	| '[' [Expression {[','] Expression}] ']'
	| '{' {ParseTable} '}'
	| TK_FUNCTION CreateFunction
	|  FunctionExp
	| TK_CLASS ClassExp
	| UnaryOP
	| TK_RAWCALL FunctionCallArgs
	| PrefixIncDec
	| DeleteExpr
	| '(' CommaExpr ')'
	| TK___LINE__
	| TK___FILE__
	.

FunctionExp = '@' CreateLambda
	.

UnaryOP =
	(
	'-' //(TK_INTEGER | TK_FLOAT)
	| '~' //TK_INTEGER
	| '!'
	| TK_TYPEOF
	| TK_RESUME
	| TK_CLONE
	) PrefixedExpr
	.

FunctionCallArgs = '(' [Expression {',' Expression}] ')'
	.

PrefixIncDec = (TK_MINUSMINUS | TK_PLUSPLUS) PrefixedExpr
	.

DeleteExpr =
	TK_DELETE PrefixedExpr
	.

ExpressionScalar =
	TK_INTEGER
	| TK_FLOAT
	| TK_STRING_LITERAL
	.

END Squirrel .

And here is the Squirrel EBNF accepted by https://www.bottlecaps.de/rr/ui to create railroad diagrams, copy the grammar bellow and paste on the Edit Grammar tab then switch to the View Diagram tab to view the railroad diagram.

//"/*" "*/" "//" lf cr  '+' lf  '+' tab
Squirrel ::=  ( Statement  )*
Statement ::=  ( IfStatement  | WhileStatement  | DoWhileStatement  | ForStatement  | ForEachStatement  | SwitchStatement  | LocalDeclStatement  | ReturnStatement  | YeldStatement  | BreakStatement  | ContinueStatement  | FunctionStatement  | ClassStatement  | EnumStatement  | Statements  | TryCatchStatement  | ThrowStatement  | ConstStatement  | CommaExpr  )  ( ';'  )?
IfStatement ::= TK_IF '(' CommaExpr ')' IfBlock  ( TK_ELSE IfBlock  )?
IfBlock ::= Statement
WhileStatement ::= TK_WHILE '(' CommaExpr ')' Statement
DoWhileStatement ::= TK_DO Statement TK_WHILE '(' CommaExpr ')'
ForStatement ::= TK_FOR '('  ( LocalDeclStatement  | CommaExpr  )? ';'  ( CommaExpr  )? ';'  ( CommaExpr  )? ')' Statement
ForEachStatement ::= TK_FOREACH '(' TK_IDENTIFIER  ( ',' TK_IDENTIFIER  )? TK_IN Expression ')' Statement
SwitchStatement ::= TK_SWITCH '(' CommaExpr ')' '{'  ( CaseStatement  )*  ( TK_DEFAULT ':' Statement  )? '}'
CaseStatement ::= TK_CASE ExpressionScalar ':'  ( Statement  )?
LocalDeclStatement ::= TK_LOCAL  ( TK_FUNCTION TK_IDENTIFIER CreateFunction  | AssignExpr  ( ',' AssignExpr  )*  )
AssignExpr ::= TK_IDENTIFIER  ( '=' Expression  )?
ReturnStatement ::= TK_RETURN  ( CommaExpr  )?
YeldStatement ::= TK_YIELD  ( CommaExpr  )?
BreakStatement ::= TK_BREAK
ContinueStatement ::= TK_CONTINUE
FunctionStatement ::= TK_FUNCTION TK_IDENTIFIER  ( "::"  ( TK_IDENTIFIER  | TK_CONSTRUCTOR  )  )* CreateFunction
CreateFunction ::= FunctionParams Statement
CreateLambda ::= FunctionParams Expression
FunctionParams ::= '('  ( TK_VARPARAMS  | OneFunctionParam  ( ',' OneFunctionParam  )*  )? ')'
OneFunctionParam ::= TK_IDENTIFIER  ( '=' Expression  )?
ClassStatement ::= TK_CLASS PrefixedExpr  ( ';'  | ClassExp  )
ClassExp ::=  ( "extends" Expression  )?  ( TK_ATTR_OPEN  ( ParseTable  )* TK_ATTR_CLOSE  )? '{'  ( ParseClass  )* '}'
ParseClass ::= ParseTableOrClass  ( ';'  )?
ParseTable ::= ParseTableOrClass  ( ','  )?
ParseTableOrClass ::=  (  ( TK_STATIC  )? TK_FUNCTION TK_IDENTIFIER  | TK_CONSTRUCTOR  ) CreateFunction  | '[' CommaExpr ']' '=' Expression  | TK_STRING_LITERAL ':' Expression  | TK_IDENTIFIER '=' Expression
EnumStatement ::= TK_ENUM TK_IDENTIFIER '{' EnumItem  ( ',' EnumItem  )* '}'
EnumItem ::= TK_IDENTIFIER  ( '=' ExpectScalar  )?
Statements ::= '{'  ( Statement  )* '}'
TryCatchStatement ::= TK_TRY Statement TK_CATCH '(' TK_IDENTIFIER ')' Statement
ThrowStatement ::= TK_THROW CommaExpr
ConstStatement ::= TK_CONST  ( TK_IDENTIFIER '=' ExpectScalar  )
ExpectScalar ::=  (  ( '-'  )?  ( TK_INTEGER  | TK_FLOAT  )  )  | TK_STRING_LITERAL  | TK_TRUE  | TK_FALSE
CommaExpr ::= Expression  ( ',' Expression  )*
Expression ::= LogicalOrExp  (  ( '='  | TK_NEWSLOT  | TK_MINUSEQ  | TK_PLUSEQ  | TK_MULEQ  | TK_DIVEQ  | TK_MODEQ  ) Expression  | '?' Expression ':' Expression  )?
LogicalOrExp ::= LogicalAndExp  ( TK_OR LogicalOrExp  )*
LogicalAndExp ::= BitwiseOrExp  ( TK_AND LogicalAndExp  )*
BitwiseOrExp ::= BitwiseXorExp  ( '|' BitwiseXorExp  )*
BitwiseXorExp ::= BitwiseAndExp  ( '^' BitwiseAndExp  )*
BitwiseAndExp ::= EqExp  ( '&' EqExp  )*
EqExp ::= CompExp  (  ( TK_EQ  | TK_NE  | TK_3WAYSCMP  ) CompExp  )*
CompExp ::= ShiftExp  (  ( '>'  | '<'  | TK_GE  | TK_LE  | TK_IN  | TK_INSTANCEOF  ) ShiftExp  )*
ShiftExp ::= PlusExp  (  ( TK_USHIFTR  | TK_SHIFTL  | TK_SHIFTR  ) PlusExp  )*
PlusExp ::= MultExp  (  ( '+'  | '-'  ) MultExp  )*
MultExp ::= PrefixedExpr  (  ( '*'  | '/'  | '%'  ) PrefixedExpr  )*
PrefixedExpr ::= Factor  ( '.'  ( TK_IDENTIFIER  | TK_CONSTRUCTOR  )  | '[' Expression ']'  |  ( TK_MINUSMINUS  | TK_PLUSPLUS  )  | FunctionCallArgs  )*
Factor ::= TK_STRING_LITERAL  | TK_BASE  | TK_IDENTIFIER  | TK_CONSTRUCTOR  | TK_THIS  | TK_DOUBLE_COLON PrefixedExpr  | TK_NULL  | TK_INTEGER  | TK_FLOAT  | TK_TRUE  | TK_FALSE  | '['  ( Expression  (  ( ','  )? Expression  )*  )? ']'  | '{'  ( ParseTable  )* '}'  | TK_FUNCTION CreateFunction  | FunctionExp  | TK_CLASS ClassExp  | UnaryOP  | TK_RAWCALL FunctionCallArgs  | PrefixIncDec  | DeleteExpr  | '(' CommaExpr ')'  | TK___LINE__  | TK___FILE__
FunctionExp ::= '@' CreateLambda
UnaryOP ::=  ( '-'  | '~'  | '!'  | TK_TYPEOF  | TK_RESUME  | TK_CLONE  ) PrefixedExpr
FunctionCallArgs ::= '('  ( Expression  ( ',' Expression  )*  )? ')'
PrefixIncDec ::=  ( TK_MINUSMINUS  | TK_PLUSPLUS  ) PrefixedExpr
DeleteExpr ::= TK_DELETE PrefixedExpr
ExpressionScalar ::= TK_INTEGER  | TK_FLOAT  | TK_STRING_LITERAL


letter ::= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_"
oct ::= '0'  .. '7'
digit ::= '0'  .. '9'
nzdigit ::= '1'  .. '9'
cr ::= '\r'
lf ::= '\n'
tab ::= '\t'
stringCh ::= ANY  '-' '"'  '-' '\'  '-' cr  '-' lf
charCh ::= ANY  '-' "'"  '-' '\'  '-' cr  '-' lf
printable ::= '\u0020'  .. '\u007e'
hex ::= digit  '+' 'a'  .. 'f'  '+' 'A'  .. 'F'
TK_IDENTIFIER  ::= letter  ( letter  | digit  )*
TK_FLOAT  ::=  ( '.' digit  ( digit  )*  (  ( 'e'  | 'E'  )  ( '+'  | '-'  )? digit  ( digit  )*  )?  | digit  ( digit  )* '.'  ( digit  )*  (  ( 'e'  | 'E'  )  ( '+'  | '-'  )? digit  ( digit  )*  )?  | digit  ( digit  )*  ( 'e'  | 'E'  )  ( '+'  | '-'  )? digit  ( digit  )*  )
TK_INTEGER  ::=  ( digit  ( digit  )*  |  ( "0x"  | "0X"  ) hex  ( hex  )*  )
TK_STRING_LITERAL  ::=  ( '@'  )? '"'  ( stringCh  | '\'  ( printable  |  ( '\r'  )? '\n'  )  )* '"'  | "'"  ( charCh  | '\'  ( printable  |  ( '\r'  )? '\n'  )  )* "'"
badString  ::= '"'  ( stringCh  | '\' printable  )*  ( cr  | lf  )  | "'"  ( charCh  | '\' printable  )*  ( cr  | lf  )
TK_AND  ::= "&&"
TK_ATTR_CLOSE  ::= "/>"
TK_ATTR_OPEN  ::= "</"
TK_BASE  ::= "base"
TK_BIT_AND_EQ  ::= "&="
TK_BIT_OR_EQ  ::= "|="
TK_BIT_SHIFT_LEFT_EQ  ::= "<<="
TK_BIT_SHIFT_RIGHT_EQ  ::= ">>="
TK_BIT_XOR_EQ  ::= "^="
TK_BREAK  ::= "break"
TK_CASE  ::= "case"
TK_CATCH  ::= "catch"
TK_CLASS  ::= "class"
TK_CLONE  ::= "clone"
TK_CONST  ::= "const"
TK_CONTINUE  ::= "continue"
TK_CONSTRUCTOR  ::= "constructor"
TK_DEFAULT  ::= "default"
TK_DELETE  ::= "delete"
TK_DIVEQ  ::= "/="
TK_DO  ::= "do"
TK_DOUBLE_COLON  ::= "::"
TK_EQ  ::= "=="
TK_ELSE  ::= "else"
TK_ENUM  ::= "enum"
TK_FALSE  ::= "false"
TK___FILE__  ::= "__FILE__"
TK_FOREACH  ::= "foreach"
TK_FOR  ::= "for"
TK_FUNCTION  ::= "function"
TK___FUNCTION__  ::= "__FUNCTION__"
TK_GOTO  ::= "goto"
TK_GE  ::= ">="
TK_IF  ::= "if"
TK_IN  ::= "in"
TK_INSTANCEOF  ::= "instanceof"
TK_LE  ::= "<="
TK___LINE__  ::= "__LINE__"
TK_LOCAL  ::= "local"
TK_MINUSEQ  ::= "-="
TK_MINUSMINUS  ::= "--"
TK_MODEQ  ::= "%="
TK_MULEQ  ::= "*="
TK_NE  ::= "!="
TK_NEWSLOT  ::= "<-"
TK_NULL  ::= "null"
TK_OR  ::= "||"
TK_PLUSEQ  ::= "+="
TK_PLUSPLUS  ::= "++"
TK_RAWCALL  ::= "rawcall"
TK_RESUME  ::= "resume"
TK_RETURN  ::= "return"
TK_SHIFTL  ::= ">>"
TK_SHIFTR  ::= "<<"
TK_STATIC  ::= "static"
TK_SWITCH  ::= "switch"
TK_THIS  ::= "this"
TK_THROW  ::= "throw"
TK_3WAYSCMP  ::= "<=>"
TK_TRUE  ::= "true"
TK_TRY  ::= "try"
TK_TYPEOF  ::= "typeof"
TK_USHIFTR  ::= ">>>"
TK_VARPARAMS  ::= "..."
TK_WHILE  ::= "while"
TK_YIELD  ::= "yield"
@mingodad
Copy link
Contributor Author

Looking through the compiler code it seems that there is a mistake here:

    void BitwiseOrExp()
    {
        BitwiseXorExp();
        for(;;) if(_token == _SC('|'))
        {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseXorExp,BW_OR); ///!!!!<<< should be BitwiseOrExp ?
        }else return;
    }

@mingodad
Copy link
Contributor Author

Or else the previous ones :

    void LogicalAndExp()
    {
        BitwiseOrExp();
        for(;;) switch(_token) {
        case TK_AND: {
            SQInteger first_exp = _fs->PopTarget();
            SQInteger trg = _fs->PushTarget();
            _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0);
            SQInteger jpos = _fs->GetCurrentPos();
            if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
            Lex(); INVOKE_EXP(&SQCompiler::LogicalAndExp); ///!!!<<< here we have full recursion could be BitwiseOrExp ?
            _fs->SnoozeOpt();
            SQInteger second_exp = _fs->PopTarget();
            if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
            _fs->SnoozeOpt();
            _fs->SetInstructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
            _es.etype = EXPR;
            break;
            }

        default:
            return;
        }
    }

@mingodad
Copy link
Contributor Author

My bad they are calling different functions to generate distinct code !

@mingodad
Copy link
Contributor Author

It seems that the for loops here are meaningless:

@@ -469,11 +470,11 @@ public:
         _es.etype = EXPR;
     }
     void LogicalOrExp()
     {
         LogicalAndExp();
-        for(;;) if(_token == TK_OR) {
+        if(_token == TK_OR) {
             SQInteger first_exp = _fs->PopTarget();
             SQInteger trg = _fs->PushTarget();
             _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0);
             SQInteger jpos = _fs->GetCurrentPos();
             if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
@@ -482,18 +483,16 @@ public:
             SQInteger second_exp = _fs->PopTarget();
             if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
             _fs->SnoozeOpt();
             _fs->SetInstructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
             _es.etype = EXPR;
-            break;
-        }else return;
+        }
     }
     void LogicalAndExp()
     {
         BitwiseOrExp();
-        for(;;) switch(_token) {
-        case TK_AND: {
+        if(_token == TK_AND) {
             SQInteger first_exp = _fs->PopTarget();
             SQInteger trg = _fs->PushTarget();
             _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0);
             SQInteger jpos = _fs->GetCurrentPos();
             if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
@@ -502,15 +501,10 @@ public:
             SQInteger second_exp = _fs->PopTarget();
             if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
             _fs->SnoozeOpt();
             _fs->SetInstructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
             _es.etype = EXPR;
-            break;
-            }
-
-        default:
-            return;
         }
     }

@mingodad
Copy link
Contributor Author

Following the code I discovered that in literal arrays the comma separator is optional, didn't knew this before.
Is this intended ?

local b = [1 2, 3 4];
print(b.len()); //Output -> 4

@albertodemichelis
Copy link
Owner

Yes, it was intended. In retrospect, I don't think it was a good decision but it really hasn't created any issue in my experience. FYI, this is also valid for function call parameters.

@mingodad
Copy link
Contributor Author

Thank you for reply an clarify it !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants