From e6221cd68ab5d76bc86fd1291963b68858577767 Mon Sep 17 00:00:00 2001 From: Ian Piumarta Date: Wed, 22 Mar 2023 18:27:38 +0900 Subject: [PATCH] Handle string and stringLiteral properly in outputNode. Update meta grammar and C grammar hooks. Add unquote mechanism. --- src/ccmeta.leg | 1678 +++++++++++++++++++++++++----------------------- 1 file changed, 870 insertions(+), 808 deletions(-) diff --git a/src/ccmeta.leg b/src/ccmeta.leg index e0dbda7..afae125 100644 --- a/src/ccmeta.leg +++ b/src/ccmeta.leg @@ -3,7 +3,7 @@ # Copyright (c) 2016-2021 Ian Piumarta and other contributors (see AUTHORS) # All rights reserved (see LICENSE) # -# Last edited: 2023-03-22 18:14:50 by piumarta on zora-10.local +# Last edited: 2023-03-22 18:26:24 by piumarta on zora-10.local %{ /* compile: leg -o ccmeta.c ccmeta.leg @@ -29,7 +29,7 @@ _DO(PostDecVariable) _DO(PostDecMember) _DO(PostDecIndex) \ _DO(GetVariable) _DO(GetMember) _DO(SetMember) _DO(GetIndex) _DO(SetIndex) \ _DO(Return) _DO(Break) _DO(Continue) _DO(Throw) _DO(Try) \ - /* _DO(Quasiquote) _DO(Unquote) */ \ + _DO(Quote) _DO(Quasiquote) /* _DO(Unquote) */ \ DO_C_PROTOS() #define META_PROTO_MAX t_Try @@ -1331,7 +1331,7 @@ typedef enum { C = 1, } language; -language lang = C, printLang = C; +language printLang = C; oop outputProgram= 0; @@ -1447,707 +1447,719 @@ oop treeCopyUnquoting(oop scope, oop obj) %} - #--------------------------------------------- C grammar -------------------------------------------------# # yylval == null => "pseudo" op, e.g., change language -- ignored by REPL # yylval == 0 => end of input file while in META mode only -start = m:mexp { yylval= m } - | META_AT META_LCB { yylval= null; lang= META } - | &{ lang == META } - s:meta { yylval= s } - | &{ lang == META } - META_RCB { yylval= null; lang= C } - | &{ lang == C } s:externalDeclaration { yylval= s } - -mexp = META_AT META_LPAREN ( @{ lang = META } s:meta_exp META_RPAREN @{ lang = C } { $$= s } - | @{ lang = C } &{ 0 } - ) +start = m:metaCatch { yylval= m } + | s:externalDeclaration { yylval= everyExternalDeclaration(s) } -error = EOL* < (!EOL .)* EOL* (!EOL .)* > &{ error(yytext), 1 } +error = EOL* < (!EOL .)* EOL* (!EOL .)* > &{ error(yytext), 1 } ### A.1.3 Identifiers # Identifiers rules # 6.4.2.1 -idOpt = id | {$$=newNullObject()} +idOpt = id | {$$=newNullObject()} + +id = { $$= new_C_id(yytext) } - + | m:metaId { $$= ensure(t_C_id, eval(globals,m)) } - + | m:mmetaId { $$= m } - + +metaId = META_AT META_LPAREN m:meta_exp META_RPAREN { $$= m} -id = { $$= new_C_id(yytext) } - -ID = &{ !is_C_keyword(yytext) } +mmetaId = META_AT META_AT META_LPAREN m:meta_exp META_RPAREN { $$= m } -name = { $$= new_C_id(yytext) } - -NAME = IDFIRST IDREST* +ID = &{ !is_C_keyword(yytext) } -IDFIRST = [a-zA-Z_] | universalCharacterName | '$' &{gnu} -IDREST = IDFIRST | [0-9] +name = { $$= new_C_id(yytext) } - -digit = [0-9] +NAME = IDFIRST IDREST* + +IDFIRST = [a-zA-Z_] | universalCharacterName | '$' &{gnu} +IDREST = IDFIRST | [0-9] + +digit = [0-9] ### A.1.4 Universal character names # universalCharacterName rule # 6.4.3 -universalCharacterName = "\\u" hexQuad | "\\U" hexQuad hexQuad +universalCharacterName = "\\u" hexQuad + | "\\U" hexQuad hexQuad -hexQuad = hexadecimalDigit hexadecimalDigit hexadecimalDigit hexadecimalDigit - -### +hexQuad = hexadecimalDigit hexadecimalDigit hexadecimalDigit hexadecimalDigit ### A.1.5 Constants # constant rule # 6.4.4 -constant = characterConstant +constant = characterConstant | floatingConstant | integerConstant - + | META_AT m:mvalue # 6.4.4.1 # integerConstant rule -integerConstant = < ( hexadecimalConstant - | octalConstant - | binaryConstant &{gnu} - | decimalConstant - ) integerSuffix? > { $$ = new_C_int(yytext); } - +integerConstant = < ( hexadecimalConstant + | octalConstant + | binaryConstant &{gnu} + | decimalConstant + ) integerSuffix? + > { $$= new_C_int(yytext); } - + | META_AT mvalue -decimalConstant = [1-9][0-9]* +decimalConstant = [1-9][0-9]* -octalConstant = '0'[0-9]* +octalConstant = '0'[0-9]* -hexadecimalConstant = hexadecimalPrefix [a-fA-F0-9]+ +hexadecimalConstant = hexadecimalPrefix [a-fA-F0-9]+ -binaryConstant = '0'[bB][01]+ +binaryConstant = '0'[bB][01]+ -hexadecimalPrefix = '0'[xX] +hexadecimalPrefix = '0'[xX] -octalDigit = [0-7] +octalDigit = [0-7] -hexadecimalDigit = [0-9A-Fa-f] +hexadecimalDigit = [0-9A-Fa-f] -integerSuffix = ( [uU][lL]?[lL]? | [lL][lL]?[uU]? ) ( imaginarySuffix &{gnu} )? +integerSuffix = ( [uU][lL]?[lL]? | [lL][lL]?[uU]? ) ( imaginarySuffix &{gnu} )? -imaginarySuffix = [ij] +imaginarySuffix = [ij] # 6.4.4.2 # floatingConstant rule -floatingConstant = <( decimalFloatingConstant | hexadecimalFloatingConstant )> { $$ = new_C_float(yytext); } - +floatingConstant = <( decimalFloatingConstant | hexadecimalFloatingConstant )> { $$= new_C_float(yytext); } - -decimalFloatingConstant = fractionalConstant exponentPart? floatingSuffix? - | digitSequence exponentPart floatingSuffix? +decimalFloatingConstant = fractionalConstant exponentPart? floatingSuffix? + | digitSequence exponentPart floatingSuffix? -hexadecimalFloatingConstant = hexadecimalPrefix hexadecimalFractionalConstant binaryExponentPart floatingSuffix? - | hexadecimalPrefix hexadecimalDigitSequence binaryExponentPart floatingSuffix? +hexadecimalFloatingConstant = hexadecimalPrefix hexadecimalFractionalConstant binaryExponentPart floatingSuffix? + | hexadecimalPrefix hexadecimalDigitSequence binaryExponentPart floatingSuffix? -fractionalConstant = digitSequence '.' digitSequence? - | '.' digitSequence +fractionalConstant = digitSequence '.' digitSequence? + | '.' digitSequence -exponentPart = [eE] [-+]? digitSequence +exponentPart = [eE] [-+]? digitSequence -digitSequence = digit+ +digitSequence = digit+ -hexadecimalFractionalConstant = hexadecimalDigitSequence '.' hexadecimalDigitSequence? - | '.' hexadecimalDigitSequence +hexadecimalFractionalConstant = hexadecimalDigitSequence '.' hexadecimalDigitSequence? + | '.' hexadecimalDigitSequence -binaryExponentPart = [pP] [-+]? digitSequence +binaryExponentPart = [pP] [-+]? digitSequence -hexadecimalDigitSequence = hexadecimalDigit+ +hexadecimalDigitSequence = hexadecimalDigit+ -floatingSuffix = [fFlL] imaginarySuffix? +floatingSuffix = [fFlL] imaginarySuffix? # 6.4.4.4 # characterConstant rule -characterConstant = < "'" cCharSequence "'" > { $$ = new_C_char(yytext) } - - | < "L'" cCharSequence "'" > { $$ = new_C_char(yytext) } - +characterConstant = < "'" cCharSequence "'" > { $$= new_C_char(yytext) } - + | < "L'" cCharSequence "'" > { $$= new_C_char(yytext) } - -cCharSequence = ( escapeSequence | !EOL [^\'\\] )* +cCharSequence = ( escapeSequence | !EOL [^\'\\] )* #' -escapeSequence = simpleEscapeSequence - | octalEscapeSequence - | hexadecimalEscapeSequence - | universalCharacterName - | '\\' EOL - | '\\' Blank+ EOL &{gnu} - | '\\' . &{gnu} +escapeSequence = simpleEscapeSequence + | octalEscapeSequence + | hexadecimalEscapeSequence + | universalCharacterName + | '\\' EOL + | '\\' Blank+ EOL &{gnu} + | '\\' . &{gnu} -simpleEscapeSequence = '\\'([\'\"?\\abfnrtv] | 'e' &{gnu}) +simpleEscapeSequence = '\\'([\'\"?\\abfnrtv] | 'e' &{gnu}) #' -octalEscapeSequence = '\\' octalDigit octalDigit? octalDigit? +octalEscapeSequence = '\\' octalDigit octalDigit? octalDigit? -hexadecimalEscapeSequence = '\\x' hexadecimalDigit+ +hexadecimalEscapeSequence = '\\x' hexadecimalDigit+ ### A.1.6 String literals # stringLiteral rule # 6.4.5 -stringLiteral = { listBegin(); } - ( s:stringLiteralPart { listAppend(s) } - )+ { $$= new_C_stringLiteral(listEnd()) } +stringLiteral = { listBegin(); } + ( s:stringLiteralPart { listAppend(s) } + | META_AT META_AT META_LPAREN m:meta_exp META_RPAREN { listAppend(m) } + )+ { $$= new_C_stringLiteral(listEnd()) } -stringLiteralPart = < '"' sCharSequence '"' > { $$= new_C_string(yytext) } - - | < 'L''"' sCharSequence '"' > { $$= new_C_string(yytext) } - +stringLiteralPart = < '"' sCharSequence '"' > { $$= new_C_string(yytext) } - + | < 'L''"' sCharSequence '"' > { $$= new_C_string(yytext) } - -sCharSequence = ( escapeSequence | !EOL [^\"\\] )* +sCharSequence = ( escapeSequence | !EOL [^\"\\] )* #" ### A.2.1 Expressions # primaryExpression rule # 6.5.1 -primaryExpression = stringLiteral | constant | id - | x:mexp { $$ = eval(globals, x) } - | l:LPAREN x:expression r:RPAREN { $$= new_C_subexpr(l, x, r) } - | l:LPAREN x:compoundStatement r:RPAREN &{gnu} { $$= new_C_subexpr(l, x, r) } +primaryExpression = META_AT ( META_LCB mstmts + #| < [a-zA-Z][a-zA-Z0-9]* > @{ printf("<%s>\n", yytext); exit(0) } + | mvalue + ) + | stringLiteral | constant | id + | l:LPAREN x:expression r:RPAREN { $$= new_C_subexpr(l, x, r) } + | l:LPAREN x:compoundStatement r:RPAREN &{gnu} { $$= new_C_subexpr(l, x, r) } # 6.5.2 # postfixExpression rule -postfixExpression = o:LPAREN l:typeName p:RPAREN - a:LCURLY r:initializerList ( c:COMMA | {c=newNullObject()} ) b:RCURLY { $$= new_C_aggregate(o, l, p, a, r, c, b) } - | l:primaryExpression - ( o:LBRACKET r:expression p:RBRACKET { l= new_C_index(l, o, r, p) } - | o:LPAREN r:argumentExpressionList p:RPAREN { l= new_C_call(l, o, r, p) } - | o:DOT r:id { l= new_C_binary(l, o, r) } - | o:PTR r:id { l= new_C_binary(l, o, r) } - | o:INC { l= new_C_postfix(l, o) } - | o:DEC { l= new_C_postfix(l, o) } - )* { $$= l } - -argumentExpressionList = { listBegin() } - ( x:assignmentExpression { listAppend(x) } - ( c:COMMA x:assignmentExpression { listAppend2(c, x) } - )* - )? { $$= listEnd() } +postfixExpression = o:LPAREN l:typeName p:RPAREN + a:LCURLY r:initializerList ( c:COMMA | {c=newNullObject()} ) b:RCURLY { $$= new_C_aggregate(o, l, p, a, r, c, b) } + | l:primaryExpression + ( o:LBRACKET r:expression p:RBRACKET { l= new_C_index(l, o, r, p) } + | o:LPAREN r:argumentExpressionList p:RPAREN { l= new_C_call(l, o, r, p) } + | o:DOT r:id { l= new_C_binary(l, o, r) } + | o:PTR r:id { l= new_C_binary(l, o, r) } + | o:INC { l= new_C_postfix(l, o) } + | o:DEC { l= new_C_postfix(l, o) } + )* { $$= l } + +argumentExpressionList = { listBegin() } + ( x:assignmentExpression { listAppend(x) } + ( c:COMMA x:assignmentExpression { listAppend2(c, x) } + )* + )? { $$= listEnd() } # 6.5.3 # unaryExpression rule -unaryExpression = o:INC x:unaryExpression { $$= new_C_prefix(o, x) } - | o:DEC x:unaryExpression { $$= new_C_prefix(o, x) } - | o:unaryOperator x:castExpression { $$= new_C_unary(o, x) } - | s:SIZEOF ( l:LPAREN t:typeName r:RPAREN { $$= new_C_sizeOf(s, l, t, r) } - | x:unaryExpression { $$= new_C_sizeOf(s, newNullObject(), x, newNullObject()) } - ) - | s:ALIGNOF ( l:LPAREN t:typeName r:RPAREN { $$= new_C_alignOf(s, l, t, r) } - | x:unaryExpression { $$= new_C_alignOf(s, newNullObject(), x, newNullObject()) } - ) &{gnu} - | asmExpr &{gnu} - | postfixExpression - -unaryOperator = BAND | STAR | PLUS | MINUS | BNOT | LNOT - | LAND &{gnu} - | REAL &{gnu} - | IMAG &{gnu} +unaryExpression = o:INC x:unaryExpression { $$= new_C_prefix(o, x) } + | o:DEC x:unaryExpression { $$= new_C_prefix(o, x) } + | o:unaryOperator x:castExpression { $$= new_C_unary(o, x) } + | s:SIZEOF ( l:LPAREN t:typeName r:RPAREN { $$= new_C_sizeOf(s, l, t, r) } + | x:unaryExpression { $$= new_C_sizeOf(s, newNullObject(), x, newNullObject()) } + ) + | s:ALIGNOF ( l:LPAREN t:typeName r:RPAREN { $$= new_C_alignOf(s, l, t, r) } + | x:unaryExpression { $$= new_C_alignOf(s, newNullObject(), x, newNullObject()) } + ) &{gnu} + | asmExpr &{gnu} + | postfixExpression + +unaryOperator = BAND | STAR | PLUS | MINUS | BNOT | LNOT + | LAND &{gnu} + | REAL &{gnu} + | IMAG &{gnu} # 6.5.4 # castExpression rule -castExpression = l:LPAREN t:typeName r:RPAREN x:castExpression { $$= new_C_cast(l, t, r, x) } - | unaryExpression +castExpression = l:LPAREN t:typeName r:RPAREN x:castExpression { $$= new_C_cast(l, t, r, x) } + | unaryExpression # 6.5.5 # multiplicativeExpression rule -multiplicativeExpression = l:castExpression - ( o:multiplicativeOperator r:castExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +multiplicativeExpression = l:castExpression + ( o:multiplicativeOperator r:castExpression { l= new_C_binary(l, o, r) } + )* { $$= l } -multiplicativeOperator = STAR | DIV | MOD +multiplicativeOperator = STAR | DIV | MOD # 6.5.6 # additiveExpression rule -additiveExpression = l:multiplicativeExpression - ( o:additiveOperator r:multiplicativeExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +additiveExpression = l:multiplicativeExpression + ( o:additiveOperator r:multiplicativeExpression { l= new_C_binary(l, o, r) } + )* { $$= l } -additiveOperator = PLUS | MINUS +additiveOperator = PLUS | MINUS # 6.5.7 # shiftExpression rule -shiftExpression = l:additiveExpression - ( o:shiftOperator r:additiveExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +shiftExpression = l:additiveExpression + ( o:shiftOperator r:additiveExpression { l= new_C_binary(l, o, r) } + )* { $$= l } -shiftOperator = LSHIFT | RSHIFT +shiftOperator = LSHIFT | RSHIFT # 6.5.8 # relationalExpression rule -relationalExpression = l:shiftExpression - ( o:relationalOperator r:shiftExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +relationalExpression = l:shiftExpression + ( o:relationalOperator r:shiftExpression { l= new_C_binary(l, o, r) } + )* { $$= l } -relationalOperator = LT | LTE | GT | GTE +relationalOperator = LT | LTE | GT | GTE # 6.5.9 # equalityExpression rule -equalityExpression = l:relationalExpression - ( o:equalityOperator r:relationalExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +equalityExpression = l:relationalExpression + ( o:equalityOperator r:relationalExpression { l= new_C_binary(l, o, r) } + )* { $$= l } -equalityOperator = EQUAL | NOT_EQUAL +equalityOperator = EQUAL | NOT_EQUAL # 6.5.10 # andExpression rule -andExpression = l:equalityExpression - ( o:BAND r:equalityExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +andExpression = l:equalityExpression + ( o:BAND r:equalityExpression { l= new_C_binary(l, o, r) } + )* { $$= l } # 6.5.11 # exclusiveOrExpression rule -exclusiveOrExpression = l:andExpression - ( o:BXOR r:andExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +exclusiveOrExpression = l:andExpression + ( o:BXOR r:andExpression { l= new_C_binary(l, o, r) } + )* { $$= l } # 6.5.12 # inclusiveOrExpression rule -inclusiveOrExpression = l:exclusiveOrExpression - ( o:BOR r:exclusiveOrExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +inclusiveOrExpression = l:exclusiveOrExpression + ( o:BOR r:exclusiveOrExpression { l= new_C_binary(l, o, r) } + )* { $$= l } # 6.5.13 # logicalAndExpression rule -logicalAndExpression = l:inclusiveOrExpression - ( o:LAND r:inclusiveOrExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +logicalAndExpression = l:inclusiveOrExpression + ( o:LAND r:inclusiveOrExpression { l= new_C_binary(l, o, r) } + )* { $$= l } # 6.5.14 # logicalOrExpression rule -logicalOrExpression = l:logicalAndExpression - ( o:LOR r:logicalAndExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +logicalOrExpression = l:logicalAndExpression + ( o:LOR r:logicalAndExpression { l= new_C_binary(l, o, r) } + )* { $$= l } # 6.5.15 # conditionalExpression rule -conditionalExpression = l:logicalOrExpression - ( q:QUESTION m:expression c:COLON r:conditionalExpression { $$= new_C_conditional(l, q, m, c, r) } - | q:QUESTION c:COLON r:conditionalExpression &{gnu} { $$= new_C_conditional(l, q, newNullObject(), c, r) } - | { $$= l } - ) +conditionalExpression = l:logicalOrExpression + ( q:QUESTION m:expression c:COLON r:conditionalExpression { $$= new_C_conditional(l, q, m, c, r) } + | q:QUESTION c:COLON r:conditionalExpression &{gnu} { $$= new_C_conditional(l, q, newNullObject(), c, r) } + | { $$= l } + ) # 6.5.16 # assignmentExpressionOpt rule -assignmentExpressionOpt = assignmentExpression | {$$=newNullObject()} +assignmentExpressionOpt = assignmentExpression | {$$=newNullObject()} -assignmentExpression = l:unaryExpression o:assignmentOperator r:assignmentExpression { $$= new_C_binary(l, o, r) } - | conditionalExpression +assignmentExpression = l:unaryExpression o:assignmentOperator r:assignmentExpression { $$= new_C_binary(l, o, r) } + | conditionalExpression -assignmentOperator = ASSIGN - | STAR_ASSIGN | DIV_ASSIGN | MOD_ASSIGN | PLUS_ASSIGN | MINUS_ASSIGN - | LSHIFT_ASSIGN | RSHIFT_ASSIGN | BAND_ASSIGN | BXOR_ASSIGN | BOR_ASSIGN +assignmentOperator = ASSIGN + | STAR_ASSIGN | DIV_ASSIGN | MOD_ASSIGN | PLUS_ASSIGN | MINUS_ASSIGN + | LSHIFT_ASSIGN | RSHIFT_ASSIGN | BAND_ASSIGN | BXOR_ASSIGN | BOR_ASSIGN # 6.5.17 # expression rule -expression = l:assignmentExpression - ( o:COMMA r:assignmentExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +expression = l:assignmentExpression + ( o:COMMA r:assignmentExpression { l= new_C_binary(l, o, r) } + )* { $$= l } -expressionOpt = expression | { $$= newNullObject() } +expressionOpt = expression | { $$= newNullObject() } -constantExpression = conditionalExpression +constantExpression = conditionalExpression ### A.2.2 Declarations # declaration rule # 6.7 -declaration = @{ C_declarationBegin() } - ( s:declarationSpecifiers - d:initDeclaratorListOpt - t:SEMI { $$= new_C_declaration(s, d, t) } - @{ C_declarationEnd() } - | - &{ C_declarationAbort() } - ) - -declarationSpecifiers = @{ int specified= 0 } { listBegin() } - ( s:storageClassSpecifier { listAppend(s) } - | s:typeSpecifier @{ specified++ } { listAppend(s) } - # Any list of specifiers and qualifiers at the start of a declaration may contain attribute specifiers - | s:attributeSpecifier &{gnu} { listAppend(s) } - | s:typedefName &{ !specified++ } { listAppend(s) } - | s:typeQualifier { listAppend(s) } - | s:functionSpecifier { listAppend(s) } - )+ { $$= listEnd() } - | &{gnu} { $$= listEmpty() } - -initDeclaratorListOpt = initDeclaratorList | { $$= listEmpty() } - -initDeclaratorList = d:initDeclarator { listWith(d) } - ( c:COMMA d:initDeclarator { listAppend2(c, d) } - )* { $$= listEnd() } - -initDeclarator = d:declarator - ( a:ASSIGN i:initializer &{ !typedeffing } { d= new_C_binary(d, a, i) } - )? { $$= d } +declaration = @{ C_declarationBegin() } + ( s:declarationSpecifiers + d:initDeclaratorListOpt + t:SEMI { $$= new_C_declaration(s, d, t) } + @{ C_declarationEnd() } + | &{ C_declarationAbort() } + ) + +declarationSpecifiers = @{ int specified= 0 } { listBegin() } + ( s:storageClassSpecifier { listAppend(s) } + | s:typeSpecifier @{ specified++ } { listAppend(s) } + # Any list of specifiers and qualifiers at the start + # of a declaration may contain attribute specifiers + | s:attributeSpecifier &{gnu} { listAppend(s) } + | s:typedefName &{ !specified++ } { listAppend(s) } + | s:typeQualifier { listAppend(s) } + | s:functionSpecifier { listAppend(s) } + )+ { $$= listEnd() } + | &{gnu} { $$= listEmpty() } + +initDeclaratorListOpt = initDeclaratorList | { $$= listEmpty() } + +initDeclaratorList = d:initDeclarator { listWith(d) } + ( c:COMMA d:initDeclarator { listAppend2(c, d) } + )* { $$= listEnd() } + +initDeclarator = d:declarator + ( a:ASSIGN i:initializer &{ !typedeffing } { d= new_C_binary(d, a, i) } + )? { $$= d } # 6.7.1 # storageClassSpecifier rule -storageClassSpecifier = TYPEDEF @{ declarationTypedef() } - | AUTO - | parameterStorageClassSpecifier - | functionStorageClassSpecifier +storageClassSpecifier = TYPEDEF @{ declarationTypedef() } + | AUTO + | parameterStorageClassSpecifier + | functionStorageClassSpecifier -parameterStorageClassSpecifier = REGISTER +parameterStorageClassSpecifier = REGISTER -functionStorageClassSpecifier = EXTERN | STATIC +functionStorageClassSpecifier = EXTERN | STATIC # 6.7.2 # typeSpecifier rule -typeSpecifier = VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | BOOL | COMPLEX - | ( BUILTIN_VA_LIST | _FLOAT128 ) - | structOrUnionSpecifier - | enumSpecifier +typeSpecifier = VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | BOOL | COMPLEX + | ( BUILTIN_VA_LIST | _FLOAT128 ) + | structOrUnionSpecifier + | enumSpecifier # 6.7.2.1 # structOrUnionSpecifier rule -structOrUnionSpecifier = s:structOrUnion - # An attribute specifier list may appear as part of a struct, union or enum specifier. It may go - # either immediately after the struct, union or enum keyword... - ( a:attributeSpecifiers &{gnu} | {a=newNullObject()} ) - ( i:idOpt ( @{ C_scopeBegin() } - l:LCURLY d:structDeclarationList r:RCURLY - @{ C_scopeEnd() } - | &{ C_scopeAbort() } - ) - # ..., or after the closing brace. - ( b:attributeSpecifiers &{gnu} | {b=newNullObject()} ) - | i:id {l=d=r=b=newNullObject()} - ) { $$= new_C_structSpec(s, a, i, l, d, r, b) } - -structOrUnion = STRUCT | UNION - -structDeclarationList = d:structDeclaration { listWith(d) } - ( d:structDeclaration { listAppend(d) } - )* { $$= listEnd() } - | &{gnu} { $$= newNullObject() } - -structDeclaration = s:specifierQualifierList d:structDeclaratorList t:SEMI - ( &SEMI { listWith(t) } - ( t:SEMI { listAppend(t) } - )* &{gnu} { t= listEnd() } - )? { $$= new_C_declaration(s, d, t) } - -specifierQualifierList = @{ int specified= 0 } { listBegin() } - ( ( t:typeSpecifier @{ specified++ } - | t:typedefName &{ !specified++ } - | t:typeQualifier - ) { listAppend(t) } - )+ { $$= listEnd() } - -structDeclaratorList = d:structDeclarator { listWith(d) } - ( c:COMMA d:structDeclarator { listAppend2(c, d) } - )* { $$= listEnd() } - | &{gnu} { $$= newNullObject() } - -structDeclarator = ( c:COLON e:constantExpression { d= new_C_structDeclarator(newNullObject(), c, e) } - | d:declarator ( c:COLON e:constantExpression | {c=e=newNullObject()} ) { d= new_C_structDeclarator(d, c, e) } - ) - # An attribute specifier list may appear immediately before the comma, = or semicolon terminating the declaration of an identifier - ( a:attributeSpecifiers { d= new_C_attribution(d, a) } - )? { $$= d } +structOrUnionSpecifier = s:structOrUnion + # An attribute specifier list may appear as part of a struct, union or enum specifier. It may go + # either immediately after the struct, union or enum keyword... + ( a:attributeSpecifiers &{gnu} | {a=newNullObject()} ) + ( i:idOpt ( @{ C_scopeBegin() } + l:LCURLY d:structDeclarationList r:RCURLY + @{ C_scopeEnd() } + | &{ C_scopeAbort() } + ) + # ..., or after the closing brace. + ( b:attributeSpecifiers &{gnu} | {b=newNullObject()} ) + | i:id {l=d=r=b=newNullObject()} + ) { $$= new_C_structSpec(s, a, i, l, d, r, b) } + +structOrUnion = STRUCT | UNION + +structDeclarationList = d:structDeclaration { listWith(d) } + ( d:structDeclaration { listAppend(d) } + )* { $$= listEnd() } + | &{gnu} { $$= newNullObject() } + +structDeclaration = s:specifierQualifierList d:structDeclaratorList t:SEMI + ( &SEMI { listWith(t) } + ( t:SEMI { listAppend(t) } + )* &{gnu} { t= listEnd() } + )? { $$= new_C_declaration(s, d, t) } + +specifierQualifierList = @{ int specified= 0 } { listBegin() } + ( ( t:typeSpecifier @{ specified++ } + | t:typedefName &{ !specified++ } + | t:typeQualifier + ) { listAppend(t) } + )+ { $$= listEnd() } + +structDeclaratorList = d:structDeclarator { listWith(d) } + ( c:COMMA d:structDeclarator { listAppend2(c, d) } + )* { $$= listEnd() } + | &{gnu} { $$= newNullObject() } + +structDeclarator = ( c:COLON e:constantExpression { d= new_C_structDeclarator(newNullObject(), c, e) } + | d:declarator ( c:COLON e:constantExpression | {c=e=newNullObject()} ) { d= new_C_structDeclarator(d, c, e) } + ) + # An attribute specifier list may appear immediately before the comma, = or semicolon terminating the declaration of an identifier + ( a:attributeSpecifiers { d= new_C_attribution(d, a) } + )? { $$= d } # 6.7.2.2 # enumSpecifier rule -enumSpecifier = e:ENUM - ( i:idOpt l:LCURLY m:enumeratorList r:RCURLY { $$= new_C_enumSpec(e, i, l, m, r) } - | i:id { $$= new_C_enumSpec(e, i, newNullObject(), newNullObject(), newNullObject()) } - ) +enumSpecifier = e:ENUM + ( i:idOpt l:LCURLY m:enumeratorList r:RCURLY { $$= new_C_enumSpec(e, i, l, m, r) } + | i:id { $$= new_C_enumSpec(e, i, newNullObject(), newNullObject(), newNullObject()) } + ) -enumeratorList = e:enumerator { listWith(e) } - ( c:COMMA e:enumerator { listAppend(c); listAppend(e) } - )* - ( c:COMMA { listAppend(c) } - )? { $$= listEnd() } +enumeratorList = e:enumerator { listWith(e) } + ( c:COMMA e:enumerator { listAppend(c); listAppend(e) } + )* + ( c:COMMA { listAppend(c) } + )? { $$= listEnd() } -enumerator = i:id - # an attribute specifier list may appear as part of an enumerator. The attribute goes after the - # enumeration constant, before =, if present. - ( a:attributeSpecifier &{gnu} { i= new_C_attribution(i, a) } - )* - ( a:ASSIGN e:constantExpression | {a=e=newNullObject()} ) { $$= new_C_enumerator(i, a, e) } +enumerator = i:id + # an attribute specifier list may appear as part of an enumerator. The attribute goes after the + # enumeration constant, before =, if present. + ( a:attributeSpecifier &{gnu} { i= new_C_attribution(i, a) } + )* + ( a:ASSIGN e:constantExpression | {a=e=newNullObject()} ) { $$= new_C_enumerator(i, a, e) } # 6.7.3 # typeQualifier rule -typeQualifier = CONST | RESTRICT | VOLATILE - | __RESTRICT +typeQualifier = CONST | RESTRICT | VOLATILE + | __RESTRICT # 6.7.4 # functionSpecifier rule -functionSpecifier = INLINE - | __INLINE +functionSpecifier = INLINE + | __INLINE # 6.7.5 # declarator rule -declarator = # An attribute specifier list may appear immediately before a declarator - a:attributeSpecifier d:declarator &{gnu} { $$= new_C_attribution(a, d) } - | p:STAR q:typeQualifierList d:declarator { $$= new_C_deref(p, q, d) } - | p:BXOR q:typeQualifierList d:declarator &{apl} { $$= new_C_block(p, q, d) } - | ( d:directDeclarator - # An attribute specifier list may appear immediately before the comma, = or semicolon terminating the declaration of an identifier - ( &{gnu} a:attributeSpecifier { d= new_C_attribution(d, a) } - # an asm (or __asm__) keyword may appear after the declarator - | &{gnu} a:asm { d= new_C_attribution(d, a) } - )* - ) { $$= d } - -directDeclarator = ( l:LPAREN d:declarator r:RPAREN { d= new_C_subexpr(l, d, r) } - | &( @{ declarationId(yytext) } ) - d:id - ) ( @{ C_scopeBegin() } - ( l:LPAREN p:parameterTypeList r:RPAREN { d= new_C_call (d, l, p, r) } - @{ C_scopeEnd() } - | l:LPAREN p:identifierListOpt r:RPAREN { d= new_C_call (d, l, p, r) } - @{ C_scopeEnd() } - | l:LBRACKET ( s:STATIC q:typeQualifierListOpt {t=newNullObject()} e:assignmentExpression - | {s=newNullObject()} q:typeQualifierList t:STATIC e:assignmentExpressionOpt - | {s=newNullObject()} q:typeQualifierListOpt t:STAR {e=newNullObject()} - | {s=newNullObject()} q:typeQualifierListOpt {t=newNullObject()} e:assignmentExpressionOpt ) r:RBRACKET { d= new_C_array(d, l, s, q, t, e, r) } - @{ C_scopeEnd() } - | &{ C_scopeAbort() } - ) - )* { $$= d } - -typeQualifierListOpt = typeQualifierList | {$$=newNullObject()} - -typeQualifierList = { listBegin() } - ( t:typeQualifier { listAppend(t) } - )* { $$= listEnd() } - -parameterTypeListOpt = parameterTypeList | {$$=newNullObject()} - -parameterTypeList = p:parameterList - ( c:COMMA v:ELLIPSIS { List_addLast(p, c); List_addLast(p, v) } - )? { $$= p } - -parameterList = p:parameterDeclaration { listWith(p) } - ( ( c:COMMA | c:SEMI &{gnu} ) { listAppend(c) } - p:parameterDeclaration { listAppend(p) } - )* { $$= listEnd() } - -parameterDeclaration = s:parameterDeclarationSpecifiers - ( d:declarator | d:abstractDeclaratorOpt ) { $$= new_C_parameter(s, d) } - -parameterDeclarationSpecifiers - = @{ int specified= 0 } { listBegin() } - ( s:parameterStorageClassSpecifier { listAppend(s) } - | s:typeSpecifier @{ specified++ } { listAppend(s) } - | s:typedefName &{ !specified++ } { listAppend(s) } - | s:typeQualifier { listAppend(s) } - | s:functionSpecifier { listAppend(s) } - )+ { $$= listEnd() } - -identifierListOpt = identifierList | {$$=newNullObject()} - -identifierList = i:id { listWith(i) } - ( c:COMMA i:id { listAppend2(c, i) } - )* { $$= listEnd() } +declarator = # An attribute specifier list may appear immediately before a declarator + a:attributeSpecifier d:declarator &{gnu} { $$= new_C_attribution(a, d) } + | p:STAR q:typeQualifierList d:declarator { $$= new_C_deref(p, q, d) } + | p:BXOR q:typeQualifierList d:declarator &{apl} { $$= new_C_block(p, q, d) } + | ( d:directDeclarator + # An attribute specifier list may appear immediately + # before the comma, = or semicolon terminating the declaration of an identifier + ( &{gnu} a:attributeSpecifier { d= new_C_attribution(d, a) } + # an asm (or __asm__) keyword may appear after the declarator + | &{gnu} a:asm { d= new_C_attribution(d, a) } + )* + ) { $$= d } + +directDeclarator = ( l:LPAREN d:declarator r:RPAREN { d= new_C_subexpr(l, d, r) } + | &( @{ declarationId(yytext) } | metaId | mmetaId ) # fix me for meta typedef + d:id + ) + ( @{ C_scopeBegin() } + ( l:LPAREN p:parameterTypeList r:RPAREN { d= new_C_call (d, l, p, r) } + @{ C_scopeEnd() } + | l:LPAREN p:identifierListOpt r:RPAREN { d= new_C_call (d, l, p, r) } + @{ C_scopeEnd() } + | l:LBRACKET ( s:STATIC q:typeQualifierListOpt {t=newNullObject()} e:assignmentExpression + | {s=newNullObject()} q:typeQualifierList + t:STATIC e:assignmentExpressionOpt + | {s=newNullObject()} q:typeQualifierListOpt + t:STAR {e=newNullObject()} + | {s=newNullObject()} q:typeQualifierListOpt {t=newNullObject()} + e:assignmentExpressionOpt ) r:RBRACKET { d= new_C_array(d, l, s, q, t, e, r) } + @{ C_scopeEnd() } + | &{ C_scopeAbort() } + ) + )* { $$= d } + +typeQualifierListOpt = typeQualifierList | {$$=newNullObject()} + +typeQualifierList = { listBegin() } + ( t:typeQualifier { listAppend(t) } + )* { $$= listEnd() } + +parameterTypeListOpt = parameterTypeList | {$$=newNullObject()} + +parameterTypeList = p:parameterList + ( c:COMMA v:ELLIPSIS { List_addLast(p, c); List_addLast(p, v) } + )? { $$= p } + +parameterList = p:parameterDeclaration { listWith(p) } + ( ( c:COMMA | c:SEMI &{gnu} ) { listAppend(c) } + p:parameterDeclaration { listAppend(p) } + )* { $$= listEnd() } + +parameterDeclaration = s:parameterDeclarationSpecifiers + ( d:declarator | d:abstractDeclaratorOpt ) { $$= new_C_parameter(s, d) } + +parameterDeclarationSpecifiers = @{ int specified= 0 } { listBegin() } + ( s:parameterStorageClassSpecifier { listAppend(s) } + | s:typeSpecifier @{ specified++ } { listAppend(s) } + | s:typedefName &{ !specified++ } { listAppend(s) } + | s:typeQualifier { listAppend(s) } + | s:functionSpecifier { listAppend(s) } + )+ { $$= listEnd() } + +identifierListOpt = identifierList | {$$=newNullObject()} + +identifierList = i:id { listWith(i) } + ( c:COMMA i:id { listAppend2(c, i) } + )* { $$= listEnd() } # 6.7.6 # typeName rule -typeName = s:specifierQualifierList d:abstractDeclaratorOpt { $$= new_C_declaration(s, d, newNullObject()) } +typeName = s:specifierQualifierList d:abstractDeclaratorOpt { $$= new_C_declaration(s, d, newNullObject()) } -abstractDeclaratorOpt = abstractDeclarator | {$$=newNullObject()} +abstractDeclaratorOpt = abstractDeclarator | {$$=newNullObject()} -abstractDeclarator = p:STAR q:typeQualifierList d:abstractDeclaratorOpt { $$= new_C_deref(p, q, d) } - | p:BXOR q:typeQualifierList d:abstractDeclaratorOpt &{apl} { $$= new_C_block(p, q, d) } - | directAbstractDeclarator +abstractDeclarator = p:STAR q:typeQualifierList d:abstractDeclaratorOpt { $$= new_C_deref(p, q, d) } + | p:BXOR q:typeQualifierList d:abstractDeclaratorOpt &{apl} { $$= new_C_block(p, q, d) } + | directAbstractDeclarator -directAbstractDeclarator= @{int nonEmpty= 0} - ( l:LPAREN d:abstractDeclarator r:RPAREN @{++nonEmpty} { d= new_C_subexpr(l, d, r) } - | {d=newNullObject()} - ) ( l:LPAREN p:parameterTypeListOpt r:RPAREN @{++nonEmpty} { d= new_C_call (d, l, p, r) } - | l:LBRACKET - ( s:STATIC q:typeQualifierListOpt {t=newNullObject()} e:assignmentExpression - | {s=newNullObject()} q:typeQualifierList t:STATIC e:assignmentExpressionOpt - | {s=newNullObject()} q:typeQualifierListOpt t:STAR {e=newNullObject()} - | {s=newNullObject()} q:typeQualifierListOpt {t=newNullObject()} e:assignmentExpressionOpt - ) r:RBRACKET @{++nonEmpty} { d= new_C_array(d, l, s, q, t, e, r) } - )* &{nonEmpty} { $$= d } +directAbstractDeclarator = @{int nonEmpty= 0} + ( l:LPAREN d:abstractDeclarator r:RPAREN @{++nonEmpty} { d= new_C_subexpr(l, d, r) } + | {d=newNullObject()} + ) + ( l:LPAREN p:parameterTypeListOpt r:RPAREN @{++nonEmpty} { d= new_C_call (d, l, p, r) } + | l:LBRACKET + ( s:STATIC q:typeQualifierListOpt {t=newNullObject()} e:assignmentExpression + | {s=newNullObject()} q:typeQualifierList t:STATIC e:assignmentExpressionOpt + | {s=newNullObject()} q:typeQualifierListOpt t:STAR {e=newNullObject()} + | {s=newNullObject()} q:typeQualifierListOpt {t=newNullObject()} e:assignmentExpressionOpt + ) r:RBRACKET @{++nonEmpty} { d= new_C_array(d, l, s, q, t, e, r) } + )* &{nonEmpty} { $$= d } # 6.7.7 # typedefName rule -typedefName = &{ isTypedefName(yytext) } { $$= new_C_id(yytext) } - - | t:TYPEOF l:LPAREN - ( x:expression r:RPAREN { $$= new_C_typeOf(t, l, newNullObject(), x, r) } - | x:typeName r:RPAREN { $$= new_C_typeOf(t, l, x, newNullObject(), r) } - ) &{gnu} +typedefName = &{ isTypedefName(yytext) } { $$= new_C_id(yytext) } - + | t:TYPEOF l:LPAREN + ( x:expression r:RPAREN { $$= new_C_typeOf(t, l, newNullObject(), x, r) } + | x:typeName r:RPAREN { $$= new_C_typeOf(t, l, x, newNullObject(), r) } + ) &{gnu} # 6.7.8 # initializer rule -initializer = l:LCURLY i:initializerList ( c:COMMA | {c=newNullObject()} ) r:RCURLY { $$= new_C_initializer(l, i, c, r) } - | assignmentExpression +initializer = l:LCURLY i:initializerList ( c:COMMA | {c=newNullObject()} ) r:RCURLY { $$= new_C_initializer(l, i, c, r) } + | assignmentExpression -initializerList = { listBegin() } - ( d:designation { listAppend(d) } - )? i:initializer { listAppend(i) } - ( c:COMMA { listAppend(c) } - ( d:designation { listAppend(d) } - )? i:initializer { listAppend(i) } - )* { $$= listEnd() } - | &{gnu} { $$= newNullObject() } +initializerList = { listBegin() } + ( d:designation { listAppend(d) } + )? i:initializer { listAppend(i) } + ( c:COMMA { listAppend(c) } + ( d:designation { listAppend(d) } + )? i:initializer { listAppend(i) } + )* { $$= listEnd() } + | &{gnu} { $$= newNullObject() } -designation = ( d:designatorList ( a:ASSIGN | {a=newNullObject()} &{gnu} ) - | d:id a:COLON &{gnu} - ) { $$= new_C_designation(d, a) } +designation = ( d:designatorList ( a:ASSIGN | {a=newNullObject()} &{gnu} ) + | d:id a:COLON &{gnu} + ) { $$= new_C_designation(d, a) } -designatorList = { listBegin() } - ( l:LBRACKET x:constantExpression r:RBRACKET { listAppend(new_C_index(newNullObject(), l, x, r)) } - | l:LBRACKET x:constantRange r:RBRACKET &{gnu} { listAppend(new_C_index(newNullObject(), l, x, r)) } - | l:DOT x:id { listAppend(new_C_binary(newNullObject(), l, x)) } - )+ { $$= listEnd() } +designatorList = { listBegin() } + ( l:LBRACKET x:constantExpression r:RBRACKET { listAppend(new_C_index(newNullObject(), l, x, r)) } + | l:LBRACKET x:constantRange r:RBRACKET &{gnu} { listAppend(new_C_index(newNullObject(), l, x, r)) } + | l:DOT x:id { listAppend(new_C_binary(newNullObject(), l, x)) } + )+ { $$= listEnd() } ### A.2.3 Statements # statement rule # 6.8 -statement = expressionStatement - | labeledStatement - | compoundStatement - | selectionStatement - | iterationStatement - | jumpStatement +statement = expressionStatement + | labeledStatement + | compoundStatement + | selectionStatement + | iterationStatement + | jumpStatement # 6.8.1 # labeledStatement rule -labeledStatement = i:id c:COLON - # an attribute specifier list may appear after the colon following a label, other than a case or default label - ( a:attributeSpecifiers &{gnu} | {a=newNullObject()} ) - s:statement { $$= new_C_label(i, c, a, s) } - | c:CASE x:constantExpression d:COLON s:statement { $$= new_C_case(c, x, d, s) } - | c:CASE x:constantRange d:COLON s:statement &{gnu} { $$= new_C_case(c, x, d, s) } - | d:DEFAULT c:COLON s:statement { $$= new_C_default(d, c, s) } +labeledStatement = i:id c:COLON + # an attribute specifier list may appear after + # the colon following a label, other than a case or default label + ( a:attributeSpecifiers &{gnu} | {a=newNullObject()} ) + s:statement { $$= new_C_label(i, c, a, s) } + | c:CASE x:constantExpression d:COLON s:statement { $$= new_C_case(c, x, d, s) } + | c:CASE x:constantRange d:COLON s:statement &{gnu} { $$= new_C_case(c, x, d, s) } + | d:DEFAULT c:COLON s:statement { $$= new_C_default(d, c, s) } # 6.8.2 # compoundStatement rule -compoundStatement = @{ C_scopeBegin() } - l:LCURLY { listBegin() } - ( x:localLabelDeclaration &{gnu} { listAppend(x) } - )* - ( x:declaration { listAppend(x) } - | x:statement { listAppend(x) } - | x:functionDefinition &{gnu} { listAppend(x) } - | !'}' &{ errmsg= "statement expected" } error - )* { x= listEnd() } - r:RCURLY { $$= new_C_compound(l, x, r) } - @{ C_scopeEnd() } - | &{ C_scopeAbort() } +compoundStatement = @{ C_scopeBegin() } + l:LCURLY { listBegin() } + ( x:localLabelDeclaration &{gnu} { listAppend(x) } + )* + ( x:declaration { listAppend(x) } + | x:statement { listAppend(x) } + | x:functionDefinition &{gnu} { listAppend(x) } + | !'}' &{ errmsg= "statement expected" } error + )* { x= listEnd() } + r:RCURLY { $$= new_C_compound(l, x, r) } + @{ C_scopeEnd() } + | &{ C_scopeAbort() } # 6.8.3 # expressionStatement rule -expressionStatement = SEMI - | x:expression s:SEMI { $$= new_C_exprStatement(x, s) } +expressionStatement = SEMI + | x:expression s:SEMI { $$= new_C_exprStatement(x, s) } # 6.8.4 # selectionStatement rule -selectionStatement = i:IF l:LPAREN x:expression r:RPAREN s:statement - ( e:ELSE t:statement | {e=t=newNullObject()} ) { $$= new_C_if(i, l, x, r, s, e, t) } - | s:SWITCH l:LPAREN x:expression r:RPAREN t:statement { $$= new_C_switch(s, l, x, r, t) } +selectionStatement = i:IF l:LPAREN x:expression r:RPAREN s:statement + ( e:ELSE t:statement | {e=t=newNullObject()} ) { $$= new_C_if(i, l, x, r, s, e, t) } + | s:SWITCH l:LPAREN x:expression r:RPAREN t:statement { $$= new_C_switch(s, l, x, r, t) } # 6.8.5 # iterationStatement rule -iterationStatement = w:WHILE l:LPAREN x:expression r:RPAREN s:statement { $$= new_C_while(w, l, x, r, s) } - | d:DO s:statement w:WHILE l:LPAREN x:expression r:RPAREN t:SEMI { $$= new_C_do(d, s, w, l, x, r, t) } - | f:FOR l:LPAREN a:expressionOpt t:SEMI b:expressionOpt u:SEMI - c:expressionOpt r:RPAREN s:statement { $$= new_C_for(f, l, a, t, b, u, c, r, s) } - | f:FOR l:LPAREN a:declaration b:expressionOpt u:SEMI - c:expressionOpt r:RPAREN s:statement { $$= new_C_for(f, l, a, newNullObject(), b, u, c, r, s) } +iterationStatement = w:WHILE l:LPAREN x:expression r:RPAREN s:statement { $$= new_C_while(w, l, x, r, s) } + | d:DO s:statement w:WHILE l:LPAREN x:expression r:RPAREN t:SEMI { $$= new_C_do(d, s, w, l, x, r, t) } + | f:FOR l:LPAREN a:expressionOpt t:SEMI b:expressionOpt u:SEMI + c:expressionOpt r:RPAREN s:statement { $$= new_C_for(f, l, a, t, b, u, c, r, s) } + | f:FOR l:LPAREN a:declaration b:expressionOpt u:SEMI + c:expressionOpt r:RPAREN s:statement { $$= new_C_for(f, l, a, newNullObject(), b, u, c, r, s) } # 6.8.6 # jumpStatement rule -jumpStatement = g:GOTO i:id t:SEMI { $$= new_C_goto(g, newNullObject(), i, t) } - | c:CONTINUE t:SEMI { $$= new_C_continue(c, t) } - | b:BREAK t:SEMI { $$= new_C_break(b, t) } - | r:RETURN x:expressionOpt t:SEMI { $$= new_C_return(r, x, t) } - | g:GOTO s:STAR x:expression t:SEMI &{gnu} { $$= new_C_goto(g, s, x, t) } +jumpStatement = g:GOTO i:id t:SEMI { $$= new_C_goto(g, newNullObject(), i, t) } + | c:CONTINUE t:SEMI { $$= new_C_continue(c, t) } + | b:BREAK t:SEMI { $$= new_C_break(b, t) } + | r:RETURN x:expressionOpt t:SEMI { $$= new_C_return(r, x, t) } + | g:GOTO s:STAR x:expression t:SEMI &{gnu} { $$= new_C_goto(g, s, x, t) } ### A.2.4 External definitions # externalDeclaration rule # 6.9 -## translationUnit = externalDeclaration+ - -externalDeclaration = { $$ = newComment(yytext); } - | ( SEMI &{gnu} - | declaration - | functionDefinition - | &. &{ errmsg= "declaration expected" } error - ) - -functionDefinition = @{ C_declarationBegin() } - ( s:functionDeclarationSpecifiers | &{gnu} {s=newNullObject()} ) - d:declarator - l:declarationListOpt - c:compoundStatement { $$= new_C_functionDef(s, d, l, c) } - @{ C_declarationEnd() } - | &{ C_declarationAbort() } - -functionDeclarationSpecifiers - = @{ int specified= 0 } { listBegin() } - ( s:functionStorageClassSpecifier { listAppend(s) } - | s:typeSpecifier @{ ++specified } { listAppend(s) } - | &{ !specified } s:typedefName @{ ++specified } { listAppend(s) } - | s:typeQualifier { listAppend(s) } - | s:functionSpecifier { listAppend(s) } - )+ { $$= listEnd() } - -declarationListOpt = declarationList | {$$=newNullObject()} - -declarationList = d:declaration { listWith(d); } - ( d:declaration { listAppend(d) } - )* { $$= listEnd() } +## translationUnit = externalDeclaration+ + +externalDeclaration = { $$= newComment(yytext); } + | ( SEMI &{gnu} + | declaration + | functionDefinition + | &. &{ errmsg= "declaration expected" } error + ) + +functionDefinition = @{ C_declarationBegin() } + ( s:functionDeclarationSpecifiers | &{gnu} {s=newNullObject()} ) + d:declarator + l:declarationListOpt + c:compoundStatement { $$= new_C_functionDef(s, d, l, c) } + @{ C_declarationEnd() } + | &{ C_declarationAbort() } + +functionDeclarationSpecifiers = @{ int specified= 0 } { listBegin() } + ( s:functionStorageClassSpecifier { listAppend(s) } + | s:typeSpecifier @{ ++specified } { listAppend(s) } + | &{ !specified } s:typedefName @{ ++specified } { listAppend(s) } + | s:typeQualifier { listAppend(s) } + | s:functionSpecifier { listAppend(s) } + )+ { $$= listEnd() } + +declarationListOpt = declarationList | {$$=newNullObject()} + +declarationList = d:declaration { listWith(d); } + ( d:declaration { listAppend(d) } + )* { $$= listEnd() } ### GNU C extensions # An attribute specifier is of the form __attribute__ ((attribute-list)). An attribute list is a # possibly empty comma-separated sequence of attributes -attributeSpecifier = a:ATTRIBUTE ll:LPAREN lr:LPAREN { listBegin() } - ( b:attribute { listAppend(b) } - )? ( c:COMMA { listAppend(c) } - ( b:attribute { listAppend(b) } - )? )* rl:RPAREN rr:RPAREN { $$= new_C_attributeSpec(a, ll, lr, listEnd(), rl, rr) } +attributeSpecifier = a:ATTRIBUTE ll:LPAREN lr:LPAREN { listBegin() } + ( b:attribute { listAppend(b) } + )? + ( c:COMMA { listAppend(c) } + ( b:attribute { listAppend(b) } + )? + )* rl:RPAREN rr:RPAREN { $$= new_C_attributeSpec(a, ll, lr, listEnd(), rl, rr) } -attributeSpecifiers = &ATTRIBUTE { listBegin() } - a:attributeSpecifier { listAppend(a) } - ( a:attributeSpecifier { listAppend(a) } - )* { $$= listEnd() } +attributeSpecifiers = &ATTRIBUTE { listBegin() } + a:attributeSpecifier { listAppend(a) } + ( a:attributeSpecifier { listAppend(a) } + )* { $$= listEnd() } # where each attribute is one of the following: # Empty. Empty attributes are ignored. @@ -2155,332 +2167,349 @@ attributeSpecifiers = &ATTRIBUTE { listBegin() } # An attribute name followed by a parenthesized list of parameters for the attribute. These parameters take one of the following forms: # An identifier. For example, mode attributes use this form. # An identifier followed by a comma and a non-empty comma-separated list of expressions. For example, format attributes use this form. -# A possibly empty comma-separated list of expressions. For example, format_arg attributes use this +# A possibly empty comma-separated list of expressions. For example, format_arg attributes use this # form with the list being a single integer constant expression, and alias attributes use # this form with the list being a single string constant. -attribute = n:name ( l:LPAREN { listBegin() } - ( p:expression { listAppend(p) } - ( p:COMMA { listAppend(p) } - p:expression { listAppend(p) } - )* - )? - r:RPAREN { p= listEnd() } - | {l=p=r=newNullObject()} - ) { $$= new_C_attribute(n, l, p, r) } - -constantRange = a:constantExpression e:ELLIPSIS b:constantExpression { $$= new_C_range(a, e, b) } - -localLabelDeclaration = l:LABEL &{gnu} { listBegin() } - i:id { listAppend(i) } - ( c:COMMA i:id { listAppend2(c, i) } - )* - ( c:COMMA { listAppend(c) } - )? - s:SEMI { $$= new_C_labelDeclaration(l, listEnd(), s) } - -asm = a:ASM l:LPAREN s:stringLiteral r:RPAREN { $$= new_C_asm(a, l, s, r) } - -asmExpr = a:ASM ( v:VOLATILE | {v=newNullObject()} ) ( g:GOTO | {g=newNullObject()} ) - l:LPAREN s:stringLiteral { listBegin() } - ( c:COLON { listAppend(c) } - ( p:asmExprArgs { listAppend(p) } - )? - ( c:COLON { listAppend(c) } - ( p:asmExprArgs { listAppend(p) } - )? - ( c:COLON { listAppend(c) } - ( p:stringLiteralList { listAppend(p) } - )? - ( c:COLON { listAppend(c) } - ( p:ids { listAppend(p) } - )? - )? - )? - )? - )? - r:RPAREN { $$= new_C_asmExpr(a, v, g, l, s, listEnd(), r) } - -asmExprArgs = a:asmExprArg { listWith(a) } - ( c:COMMA a:asmExprArg { listAppend2(c, a) } - )* { $$= listEnd() } - -asmExprArg = s:stringLiteral ( l:LPAREN e:expression r:RPAREN | {l=e=r=newNullObject()} ){ $$= new_C_asmExprArg(s, l, e, r) } - -stringLiteralList = s:stringLiteral { listWith(s) } - ( c:COMMA s:stringLiteral { listAppend2(c, s) } - )* { $$= listEnd() } - -ids = i:id { listWith(i) } - ( c:COMMA i:id { listAppend2(c, i) } - )* { $$= listEnd() } +attribute = n:name + ( l:LPAREN { listBegin() } + ( p:expression { listAppend(p) } + ( p:COMMA { listAppend(p) } + p:expression { listAppend(p) } + )* + )? + r:RPAREN { p= listEnd() } + | {l=p=r=newNullObject()} + ) { $$= new_C_attribute(n, l, p, r) } + +constantRange = a:constantExpression e:ELLIPSIS b:constantExpression { $$= new_C_range(a, e, b) } + +localLabelDeclaration = l:LABEL &{gnu} { listBegin() } + i:id { listAppend(i) } + ( c:COMMA i:id { listAppend2(c, i) } + )* + ( c:COMMA { listAppend(c) } + )? + s:SEMI { $$= new_C_labelDeclaration(l, listEnd(), s) } + +asm = a:ASM l:LPAREN s:stringLiteral r:RPAREN { $$= new_C_asm(a, l, s, r) } + +asmExpr = a:ASM ( v:VOLATILE | {v=newNullObject()} ) ( g:GOTO | {g=newNullObject()} ) + l:LPAREN s:stringLiteral { listBegin() } + ( c:COLON { listAppend(c) } + ( p:asmExprArgs { listAppend(p) } + )? + ( c:COLON { listAppend(c) } + ( p:asmExprArgs { listAppend(p) } + )? + ( c:COLON { listAppend(c) } + ( p:stringLiteralList { listAppend(p) } + )? + ( c:COLON { listAppend(c) } + ( p:ids { listAppend(p) } + )? + )? + )? + )? + )? + r:RPAREN { $$= new_C_asmExpr(a, v, g, l, s, listEnd(), r) } + +asmExprArgs = a:asmExprArg { listWith(a) } + ( c:COMMA a:asmExprArg { listAppend2(c, a) } + )* { $$= listEnd() } + +asmExprArg = s:stringLiteral ( l:LPAREN e:expression r:RPAREN | {l=e=r=newNullObject()} ){ $$= new_C_asmExprArg(s, l, e, r) } + +stringLiteralList = s:stringLiteral { listWith(s) } + ( c:COMMA s:stringLiteral { listAppend2(c, s) } + )* { $$= listEnd() } + +ids = i:id { listWith(i) } + ( c:COMMA i:id { listAppend2(c, i) } + )* { $$= listEnd() } ### -ASSIGN = '=' !'=' { $$= newToken("=" ) } - -COLON = ':' { $$= newToken(":" ) } - -COMMA = ',' { $$= newToken("," ) } - -QUESTION = '?' { $$= newToken("?" ) } - -SEMI = ';' { $$= newToken(";" ) } - - -PTR = "->" { $$= newToken("->" ) } - - -DOT = '.' !'.' { $$= newToken("." ) } - -ELLIPSIS = '...' { $$= newToken("..." ) } - - -LPAREN = '(' { $$= newToken("(" ) } - -RPAREN = ')' { $$= newToken(")" ) } - -LBRACKET = '[' { $$= newToken("[" ) } - -RBRACKET = ']' { $$= newToken("]" ) } - -LCURLY = '{' { $$= newBegin( ) } - -RCURLY = '}' { $$= newEnd ( ) } - - -EQUAL = "==" { $$= newToken("==" ) } - -NOT_EQUAL = "!=" { $$= newToken("!=" ) } - -LTE = "<=" { $$= newToken("<=" ) } - -LT = "<" !'=' { $$= newToken("<" ) } - -GTE = ">=" { $$= newToken(">=" ) } - -GT = ">" !'=' { $$= newToken(">" ) } - - -DIV = '/' ![=*] { $$= newToken("/" ) } - -DIV_ASSIGN = "/=" { $$= newToken("/=" ) } - -PLUS = '+' ![+=] { $$= newToken("+" ) } - -PLUS_ASSIGN = "+=" { $$= newToken("+=" ) } - -INC = "++" { $$= newToken("++" ) } - -MINUS = '-' ![-=] { $$= newToken("-" ) } - -MINUS_ASSIGN = "-=" { $$= newToken("-=" ) } - -DEC = "--" { $$= newToken("--" ) } - -STAR = '*' !'=' { $$= newToken("*" ) } - -STAR_ASSIGN = "*=" { $$= newToken("*=" ) } - -MOD = '%' !'=' { $$= newToken("%" ) } - -MOD_ASSIGN = "%=" { $$= newToken("%=" ) } - -RSHIFT = ">>" !'=' { $$= newToken(">>" ) } - -RSHIFT_ASSIGN = ">>=" { $$= newToken(">>=" ) } - -LSHIFT = "<<" !'=' { $$= newToken("<<" ) } - -LSHIFT_ASSIGN = "<<=" { $$= newToken("<<=" ) } - - -LAND = "&&" { $$= newToken("&&" ) } - -LNOT = '!' !'=' { $$= newToken("!" ) } - -LOR = "||" { $$= newToken("||" ) } - - -BAND = '&' ![&=] { $$= newToken("&" ) } - -BAND_ASSIGN = "&=" { $$= newToken("&=" ) } - -BNOT = '~' { $$= newToken("~" ) } - -BOR = '|' ![|=] { $$= newToken("|" ) } - -BOR_ASSIGN = "|=" { $$= newToken("|=" ) } - -BXOR = '^' !'=' { $$= newToken("^" ) } - -BXOR_ASSIGN = "^=" { $$= newToken("^=" ) } - - -ALIGNOF = '__alignof__' !IDREST { $$= newToken("__alignof__" ) } - - | '__alignof' !IDREST { $$= newToken("__alignof" ) } - -ASM = 'asm' !IDREST { $$= newToken("asm" ) } - - | '__asm' !IDREST { $$= newToken("__asm" ) } - - | '__asm__' !IDREST { $$= newToken("__asm__" ) } - -ATTRIBUTE = '__attribute__' !IDREST { $$= newToken("__attribute__") } - -AUTO = 'auto' !IDREST { $$= newToken("auto" ) } - -BOOL = '_Bool' !IDREST { $$= newToken("_Bool" ) } - -BREAK = 'break' !IDREST { $$= newToken("break" ) } - -CASE = 'case' !IDREST { $$= newToken("case" ) } - -CHAR = 'char' !IDREST { $$= newToken("char" ) } - -COMPLEX = '_Complex' !IDREST { $$= newToken("_Complex" ) } - - | '__complex__' !IDREST &{gnu} { $$= newToken("__complex__" ) } - -CONST = 'const' !IDREST { $$= newToken("const" ) } - - | '__const' !IDREST { $$= newToken("__const" ) } - -CONTINUE = 'continue' !IDREST { $$= newToken("continue" ) } - -DEFAULT = 'default' !IDREST { $$= newToken("default" ) } - -DO = 'do' !IDREST { $$= newToken("do" ) } - -DOUBLE = 'double' !IDREST { $$= newToken("double" ) } - -ELSE = 'else' !IDREST { $$= newToken("else" ) } - -ENUM = 'enum' !IDREST { $$= newToken("enum" ) } - -EXTERN = 'extern' !IDREST { $$= newToken("extern" ) } - -FLOAT = 'float' !IDREST { $$= newToken("float" ) } - -FOR = 'for' !IDREST { $$= newToken("for" ) } - -GOTO = 'goto' !IDREST { $$= newToken("goto" ) } - -IF = 'if' !IDREST { $$= newToken("if" ) } - -INLINE = 'inline' !IDREST { $$= newToken("inline" ) } - - | '__inline__' !IDREST &{gnu} { $$= newToken("__inline__" ) } - -INT = 'int' !IDREST { $$= newToken("int" ) } - -LONG = 'long' !IDREST { $$= newToken("long" ) } - -REGISTER = 'register' !IDREST { $$= newToken("register" ) } - -RESTRICT = 'restrict' !IDREST { $$= newToken("restrict" ) } - -RETURN = 'return' !IDREST { $$= newToken("return" ) } - -SHORT = 'short' !IDREST { $$= newToken("short" ) } - -SIGNED = 'signed' !IDREST { $$= newToken("signed" ) } - -SIZEOF = 'sizeof' !IDREST { $$= newToken("sizeof" ) } - -STATIC = 'static' !IDREST { $$= newToken("static" ) } - -STRUCT = 'struct' !IDREST { $$= newToken("struct" ) } - -SWITCH = 'switch' !IDREST { $$= newToken("switch" ) } - -TYPEDEF = 'typedef' !IDREST { $$= newToken("typedef" ) } - -TYPEOF = 'typeof' !IDREST { $$= newToken("typeof" ) } - - | '__typeof__' !IDREST { $$= newToken("__typeof__" ) } - -UNION = 'union' !IDREST { $$= newToken("union" ) } - -UNSIGNED = 'unsigned' !IDREST { $$= newToken("unsigned" ) } - -VOID = 'void' !IDREST { $$= newToken("void" ) } - -VOLATILE = 'volatile' !IDREST { $$= newToken("volatile" ) } - -WHILE = 'while' !IDREST { $$= newToken("while" ) } - - -IMAG = '__imag__' !IDREST &{gnu} { $$= newToken("__imag__" ) } - -LABEL = '__label__' !IDREST &{gnu} { $$= newToken("__label__") } - -REAL = '__real__' !IDREST &{gnu} { $$= newToken("__real__" ) } - - -BUILTIN_VA_LIST = '__builtin_va_list' !IDREST &{gnu} { $$= newToken("__builtin_va_list" ) } - -__RESTRICT = '__restrict' !IDREST &{gnu} { $$= newToken("__restrict" ) } - -__INLINE = '__inline' !IDREST &{gnu} { $$= newToken("__inline" ) } - -_FLOAT128 = '_Float128' !IDREST &{gnu} { $$= newToken("_Float128" ) } - +ASSIGN = '=' !'=' { $$= newToken("=" ) } - +COLON = ':' { $$= newToken(":" ) } - +COMMA = ',' { $$= newToken("," ) } - +QUESTION = '?' { $$= newToken("?" ) } - +SEMI = ';' { $$= newToken(";" ) } - + +PTR = "->" { $$= newToken("->" ) } - + +DOT = '.' !'.' { $$= newToken("." ) } - +ELLIPSIS = '...' { $$= newToken("..." ) } - + +LPAREN = '(' { $$= newToken("(" ) } - +RPAREN = ')' { $$= newToken(")" ) } - +LBRACKET = '[' { $$= newToken("[" ) } - +RBRACKET = ']' { $$= newToken("]" ) } - +LCURLY = '{' { $$= newBegin( ) } - +RCURLY = '}' { $$= newEnd ( ) } - + +EQUAL = "==" { $$= newToken("==" ) } - +NOT_EQUAL = "!=" { $$= newToken("!=" ) } - +LTE = "<=" { $$= newToken("<=" ) } - +LT = "<" !'=' { $$= newToken("<" ) } - +GTE = ">=" { $$= newToken(">=" ) } - +GT = ">" !'=' { $$= newToken(">" ) } - + +DIV = '/' ![=*] { $$= newToken("/" ) } - +DIV_ASSIGN = "/=" { $$= newToken("/=" ) } - +PLUS = '+' ![+=] { $$= newToken("+" ) } - +PLUS_ASSIGN = "+=" { $$= newToken("+=" ) } - +INC = "++" { $$= newToken("++" ) } - +MINUS = '-' ![-=] { $$= newToken("-" ) } - +MINUS_ASSIGN = "-=" { $$= newToken("-=" ) } - +DEC = "--" { $$= newToken("--" ) } - +STAR = '*' !'=' { $$= newToken("*" ) } - +STAR_ASSIGN = "*=" { $$= newToken("*=" ) } - +MOD = '%' !'=' { $$= newToken("%" ) } - +MOD_ASSIGN = "%=" { $$= newToken("%=" ) } - +RSHIFT = ">>" !'=' { $$= newToken(">>" ) } - +RSHIFT_ASSIGN = ">>=" { $$= newToken(">>=" ) } - +LSHIFT = "<<" !'=' { $$= newToken("<<" ) } - +LSHIFT_ASSIGN = "<<=" { $$= newToken("<<=" ) } - + +LAND = "&&" { $$= newToken("&&" ) } - +LNOT = '!' !'=' { $$= newToken("!" ) } - +LOR = "||" { $$= newToken("||" ) } - + +BAND = '&' ![&=] { $$= newToken("&" ) } - +BAND_ASSIGN = "&=" { $$= newToken("&=" ) } - +BNOT = '~' { $$= newToken("~" ) } - +BOR = '|' ![|=] { $$= newToken("|" ) } - +BOR_ASSIGN = "|=" { $$= newToken("|=" ) } - +BXOR = '^' !'=' { $$= newToken("^" ) } - +BXOR_ASSIGN = "^=" { $$= newToken("^=" ) } - + +ALIGNOF = '__alignof__' !IDREST { $$= newToken("__alignof__" ) } - + | '__alignof' !IDREST { $$= newToken("__alignof" ) } - + +ASM = 'asm' !IDREST { $$= newToken("asm" ) } - + | '__asm' !IDREST { $$= newToken("__asm" ) } - + | '__asm__' !IDREST { $$= newToken("__asm__" ) } - + +ATTRIBUTE = '__attribute__' !IDREST { $$= newToken("__attribute__" ) } - +AUTO = 'auto' !IDREST { $$= newToken("auto" ) } - +BOOL = '_Bool' !IDREST { $$= newToken("_Bool" ) } - +BREAK = 'break' !IDREST { $$= newToken("break" ) } - +CASE = 'case' !IDREST { $$= newToken("case" ) } - +CHAR = 'char' !IDREST { $$= newToken("char" ) } - +COMPLEX = '_Complex' !IDREST { $$= newToken("_Complex" ) } - + | '__complex__' !IDREST &{gnu} { $$= newToken("__complex__" ) } - +CONST = 'const' !IDREST { $$= newToken("const" ) } - + | '__const' !IDREST { $$= newToken("__const" ) } - +CONTINUE = 'continue' !IDREST { $$= newToken("continue" ) } - +DEFAULT = 'default' !IDREST { $$= newToken("default" ) } - +DO = 'do' !IDREST { $$= newToken("do" ) } - +DOUBLE = 'double' !IDREST { $$= newToken("double" ) } - +ELSE = 'else' !IDREST { $$= newToken("else" ) } - +ENUM = 'enum' !IDREST { $$= newToken("enum" ) } - +EXTERN = 'extern' !IDREST { $$= newToken("extern" ) } - +FLOAT = 'float' !IDREST { $$= newToken("float" ) } - +FOR = 'for' !IDREST { $$= newToken("for" ) } - +GOTO = 'goto' !IDREST { $$= newToken("goto" ) } - +IF = 'if' !IDREST { $$= newToken("if" ) } - +INLINE = 'inline' !IDREST { $$= newToken("inline" ) } - + | '__inline__' !IDREST &{gnu} { $$= newToken("__inline__" ) } - +INT = 'int' !IDREST { $$= newToken("int" ) } - +LONG = 'long' !IDREST { $$= newToken("long" ) } - +REGISTER = 'register' !IDREST { $$= newToken("register" ) } - +RESTRICT = 'restrict' !IDREST { $$= newToken("restrict" ) } - +RETURN = 'return' !IDREST { $$= newToken("return" ) } - +SHORT = 'short' !IDREST { $$= newToken("short" ) } - +SIGNED = 'signed' !IDREST { $$= newToken("signed" ) } - +SIZEOF = 'sizeof' !IDREST { $$= newToken("sizeof" ) } - +STATIC = 'static' !IDREST { $$= newToken("static" ) } - +STRUCT = 'struct' !IDREST { $$= newToken("struct" ) } - +SWITCH = 'switch' !IDREST { $$= newToken("switch" ) } - +TYPEDEF = 'typedef' !IDREST { $$= newToken("typedef" ) } - +TYPEOF = 'typeof' !IDREST { $$= newToken("typeof" ) } - + | '__typeof__' !IDREST { $$= newToken("__typeof__" ) } - +UNION = 'union' !IDREST { $$= newToken("union" ) } - +UNSIGNED = 'unsigned' !IDREST { $$= newToken("unsigned" ) } - +VOID = 'void' !IDREST { $$= newToken("void" ) } - +VOLATILE = 'volatile' !IDREST { $$= newToken("volatile" ) } - +WHILE = 'while' !IDREST { $$= newToken("while" ) } - + +IMAG = '__imag__' !IDREST &{gnu} { $$= newToken("__imag__" ) } - +LABEL = '__label__' !IDREST &{gnu} { $$= newToken("__label__" ) } - +REAL = '__real__' !IDREST &{gnu} { $$= newToken("__real__" ) } - + +BUILTIN_VA_LIST = '__builtin_va_list' !IDREST &{gnu} { $$= newToken("__builtin_va_list" ) } - +__RESTRICT = '__restrict' !IDREST &{gnu} { $$= newToken("__restrict" ) } - +__INLINE = '__inline' !IDREST &{gnu} { $$= newToken("__inline" ) } - +_FLOAT128 = '_Float128' !IDREST &{gnu} { $$= newToken("_Float128" ) } - #--------------------------------------------- Meta grammar ----------------------------------------------# # the semicolon has to be explicit with no space eaten afterwards to prevent the # input buffer from moving past it before redirecting input from the imported file -meta = META_IMPORT s:META_STRING ";" { readEvalPrint(globals, get(s, String, value)); $$= 0 } - | s:meta_stmt { $$ = s } - | !. { $$ = 0 } # signal end of current input file - -meta_stmt = s:meta_block { $$ = s } - | META_SEMICOLON { $$ = null } - | l:META_IDENT p:meta_paramList e:meta_block { $$ = newFunc(l, p, e, null) } - | META_IF META_LPAREN c:meta_exp META_RPAREN t:meta_stmt META_ELSE f:meta_stmt { $$ = newIf(c, t, f ) } - | META_IF META_LPAREN c:meta_exp META_RPAREN t:meta_stmt { $$ = newIf(c, t, null) } - | META_WHILE META_LPAREN c:meta_exp META_RPAREN s:meta_stmt { $$ = newWhile(c, s) } - | META_DO s:meta_stmt META_WHILE META_LPAREN c:meta_exp META_RPAREN { $$ = newDo(s, c) } - | META_FOR META_LPAREN i:meta_ident META_IN e:meta_exp META_RPAREN s:meta_stmt { $$ = newForIn(i, e, s) } - | META_FOR META_LPAREN i:meta_stmt c:meta_stmt u:meta_exp META_RPAREN s:meta_stmt { $$ = newFor(i, c, u, s) } - | s:meta_switch { $$ = s } - | META_RETURN e:meta_exp { $$ = newReturn(e) } - | META_RETURN { $$ = newReturn(null) } - | META_BREAK { $$ = newBreak() } - | META_CONTINUE { $$ = newContinue() } - | META_THROW e:meta_exp { $$ = newUnary(Throw_proto, e) } - | t:meta_try { $$ = t } - | e:meta_exp META_SEMICOLON { $$ = e } - -meta_block = META_LCB m:meta_makeMap - ( s:meta_stmt { map_append(m, s) } +metaCatch = META_AT ( META_IMPORT s:META_STRING ";" { readEvalPrint(globals, get(s, String, value)); $$= 0 } + | m:mvalue { $$= m } + | META_LCB s:mstmts { $$= s } + ) + +mvalue = ( i:META_IDENT { i= newGetVariable(i) } ( a:meta_argumentList { oop k = map_pop(a); i = newCall(i, a, k) } # call a function with argument + | { i = is(Function, eval(globals, i)) ? newCall(i, makeMap(), null) : i } # without + ) + | META_LPAREN ( i:meta_exp ) META_RPAREN + ) { $$= eval(globals, i) } + +mstmts = ( s:eval_stmt )* META_RCB { $$= s } # return the last stmt + +eval_stmt = s:meta_stmt { $$= eval(globals, s) } # evaluate each statement at the time + +meta_stmt = s:meta_block { $$= s } + | META_SEMICOLON { $$= null } + | l:META_IDENT p:meta_paramList e:meta_block { $$= newFunc(l, p, e, null) } + | META_IF META_LPAREN c:meta_exp META_RPAREN t:meta_stmt META_ELSE f:meta_stmt { $$= newIf(c, t, f ) } + | META_IF META_LPAREN c:meta_exp META_RPAREN t:meta_stmt { $$= newIf(c, t, null) } + | META_WHILE META_LPAREN c:meta_exp META_RPAREN s:meta_stmt { $$= newWhile(c, s) } + | META_DO s:meta_stmt META_WHILE META_LPAREN c:meta_exp META_RPAREN { $$= newDo(s, c) } + | META_FOR META_LPAREN i:meta_ident META_IN e:meta_exp META_RPAREN s:meta_stmt { $$= newForIn(i, e, s) } + | META_FOR META_LPAREN i:meta_stmt c:meta_stmt u:meta_exp META_RPAREN s:meta_stmt { $$= newFor(i, c, u, s) } + | s:meta_switch { $$= s } + | META_RETURN e:meta_exp { $$= newReturn(e) } + | META_RETURN { $$= newReturn(null) } + | META_BREAK { $$= newBreak() } + | META_CONTINUE { $$= newContinue() } + | META_THROW e:meta_exp { $$= newUnary(Throw_proto, e) } + | t:meta_try { $$= t } + | e:meta_exp META_SEMICOLON { $$= e } + +meta_block = META_LCB m:meta_makeMap + ( s:meta_stmt { map_append(m, s) } ) * - ( s:meta_exp { map_append(m, s) } + ( s:meta_exp { map_append(m, s) } ) ? - META_RCB { $$ = newBlock(m) } - -meta_exp = META_VAR l:meta_ident META_ASSIGN e:meta_exp { $$ = newDeclaration(l, e) } -# | META_SYNTAX l:META_IDENT p:meta_paramList q:META_IDENT e:meta_block { $$ = (map_append(p, q), newFunc(l, p, e, makeInteger(2))) } -# | META_SYNTAX p:meta_paramList q:META_IDENT e:meta_block { $$ = (map_append(p, q), newFunc(null, p, e, makeInteger(2))) } -# | META_SYNTAX l:META_IDENT p:meta_paramList e:meta_block { $$ = newFunc(l, p, e, makeInteger(1)) } -# | META_SYNTAX p:meta_paramList e:meta_block { $$ = newFunc(null, p, e, makeInteger(1)) } - | l:META_IDENT o:meta_assignOp e:meta_exp { $$ = newAssign(Assign_proto, l, o, e) } - | l:meta_postfix META_DOT i:META_IDENT o:meta_assignOp e:meta_exp { $$ = newSetMap(SetMember_proto, l, i, o, e) } - | l:meta_postfix META_LBRAC i:meta_exp META_RBRAC o:meta_assignOp e:meta_exp { $$ = newSetMap(SetIndex_proto, l, i, o, e) } - | l:meta_syntax2 a:meta_argumentList s:meta_block { $$ = (map_append(a, s), apply(globals, globals, l, a, a)) } - | c:meta_cond { $$ = c } - -meta_ident = l:META_IDENT { $$ = l } -# | META_AT n:meta_prefix { $$ = newUnary(Unquote_proto, n) } + META_RCB { $$= newBlock(m) } + +meta_exp = META_VAR l:meta_ident META_ASSIGN e:meta_exp { $$= newDeclaration(l, e) } +# | META_SYNTAX l:META_IDENT p:meta_paramList q:META_IDENT e:meta_block { $$= (map_append(p, q), newFunc(l, p, e, makeInteger(2))) } +# | META_SYNTAX p:meta_paramList q:META_IDENT e:meta_block { $$= (map_append(p, q), newFunc(null, p, e, makeInteger(2))) } +# | META_SYNTAX l:META_IDENT p:meta_paramList e:meta_block { $$= newFunc(l, p, e, makeInteger(1)) } +# | META_SYNTAX p:meta_paramList e:meta_block { $$= newFunc(null, p, e, makeInteger(1)) } + | m:MO_OPERATION { $$= m } + | l:META_IDENT o:meta_assignOp e:meta_exp { $$= newAssign(Assign_proto, l, o, e) } + | l:meta_postfix META_DOT i:META_IDENT o:meta_assignOp e:meta_exp { $$= newSetMap(SetMember_proto, l, i, o, e) } + | l:meta_postfix META_LBRAC i:meta_exp META_RBRAC o:meta_assignOp e:meta_exp { $$= newSetMap(SetIndex_proto, l, i, o, e) } + | l:meta_syntax2 a:meta_argumentList s:meta_block { $$= (map_append(a, s), apply(globals, globals, l, a, a)) } + | c:meta_cond { $$= c } + +meta_ident = l:META_IDENT { $$= l } +# | META_AT n:meta_prefix { $$= newUnary(Unquote_proto, n) } meta_syntax2 = < [a-zA-Z_][a-zA-Z0-9_]* > - &{ null != getSyntaxId(2, intern(yytext)) } -- { $$ = getSyntaxId(2, intern(yytext)) } - -meta_try = META_TRY t:meta_stmt i:meta_null c:meta_null f:meta_null - ( META_CATCH META_LPAREN i:META_IDENT META_RPAREN c:meta_stmt ) ? - ( META_FINALLY f:meta_stmt ) ? { $$ = newTry(t, i, c, f) } - -meta_null = { $$ = null } - -meta_assignOp = META_ASSIGN { $$= null } - | META_ASSIGNADD { $$= Add_symbol } - | META_ASSIGNSUB { $$= Sub_symbol } - | META_ASSIGNMUL { $$= Mul_symbol } - | META_ASSIGNDIV { $$= Div_symbol } - | META_ASSIGNMOD { $$= Mod_symbol } - | META_ASSIGNBITOR { $$= Bitor_symbol } - | META_ASSIGNBITXOR { $$= Bitxor_symbol } - | META_ASSIGNBITAND { $$= Bitand_symbol } - | META_ASSIGNSHLEFT { $$= Shleft_symbol } - | META_ASSIGNSHRIGHT { $$= Shright_symbol } - -meta_switch = META_SWITCH META_LPAREN e:meta_exp META_RPAREN - META_LCB statements:meta_makeMap labels:meta_makeMap - ( META_CASE l:meta_exp META_COLON { map_set(labels, eval(globals, l), makeInteger(map_size(statements))) } - | META_DEFAULT META_COLON { map_set(labels, __default___symbol, makeInteger(map_size(statements))) } - | s:meta_stmt { map_append(statements, s) } - )* - META_RCB { $$= newSwitch(e, labels, statements) } - -meta_cond = c:meta_logor META_QUERY t:meta_exp META_COLON f:meta_cond { $$ = newIf(c, t, f) } - | meta_logor - -meta_logor = l:meta_logand - ( META_LOGOR r:meta_logand { l = newBinary(Logor_proto, l, r) } - )* { $$ = l } - -meta_logand = l:meta_bitor - ( META_LOGAND r:meta_bitor { l = newBinary(Logand_proto, l, r) } - )* { $$ = l } - -meta_bitor = l:meta_bitxor - ( META_BITOR r:meta_bitxor { l = newBinary(Bitor_proto, l, r) } - )* { $$ = l } - -meta_bitxor = l:meta_bitand - ( META_BITXOR r:meta_bitand { l = newBinary(Bitxor_proto, l, r) } - )* { $$ = l } - -meta_bitand = l:meta_eq - ( META_BITAND r:meta_eq { l = newBinary(Bitand_proto, l, r) } - )* { $$ = l } - -meta_eq = l:meta_ineq - ( META_EQUAL r:meta_ineq { l = newBinary(Equal_proto, l, r) } - | META_NOTEQ r:meta_ineq { l = newBinary(Noteq_proto, l, r) } - )* { $$ = l } - -meta_ineq = l:meta_shift - ( META_LESS r:meta_shift { l = newBinary(Less_proto, l, r) } - | META_LESSEQ r:meta_shift { l = newBinary(Lesseq_proto, l, r) } - | META_GREATEREQ r:meta_shift { l = newBinary(Greatereq_proto, l, r) } - | META_GREATER r:meta_shift { l = newBinary(Greater_proto, l, r) } - )* { $$ = l } - -meta_shift = l:meta_sum - ( META_SHLEFT r:meta_sum { l = newBinary(Shleft_proto, l, r) } - | META_SHRIGHT r:meta_sum { l = newBinary(Shright_proto, l, r) } - )* { $$ = l } - -meta_sum = l:meta_prod - ( META_PLUS r:meta_prod { l = newBinary(Add_proto, l, r) } - | META_MINUS r:meta_prod { l = newBinary(Sub_proto, l, r) } - )* { $$ = l } - -meta_prod = l:meta_prefix - ( META_MULTI r:meta_prefix { l = newBinary(Mul_proto, l, r) } - | META_DIVIDE r:meta_prefix { l = newBinary(Div_proto, l, r) } - | META_MODULO r:meta_prefix { l = newBinary(Mod_proto, l, r) } - )* { $$ = l } - -meta_prefix = META_PLUS n:meta_prefix { $$= n } - | META_NEGATE n:meta_prefix { $$= newUnary(Neg_proto, n) } - | META_TILDE n:meta_prefix { $$= newUnary(Com_proto, n) } - | META_PLING n:meta_prefix { $$= newUnary(Not_proto, n) } - | META_PLUSPLUS n:meta_prefix { $$= newPreIncrement(n) } - | META_MINUSMINUS n:meta_prefix { $$= newPreDecrement(n) } -# | META_BACKTICK n:meta_prefix { $$ = newUnary(Quasiquote_proto, n) } -# | META_AT n:meta_prefix { $$ = newUnary(Unquote_proto, n) } - | n:meta_postfix { $$= n } - -meta_postfix = i:meta_value ( META_DOT s:META_IDENT a:meta_argumentList { i = newInvoke(i, s, a) } - | META_DOT s:META_IDENT !meta_assignOp { i = newGetMap(GetMember_proto, i, s) } - | META_LBRAC p:meta_exp META_RBRAC !meta_assignOp { i = newGetMap(GetIndex_proto, i, p) } - | a:meta_argumentList { oop k = map_pop(a); i = newCall(i, a, k) } - | META_PLUSPLUS { i = newPostIncrement(i) } - | META_MINUSMINUS { i = newPostDecrement(i) } - ) * { $$ = i } - -meta_paramList = META_LPAREN m:meta_makeMap - ( i:META_IDENT { map_append(m, i) } - ( META_COMMA i:META_IDENT { map_append(m, i) } - ) * - ) ? - META_RPAREN { $$ = m } + &{ null != getSyntaxId(2, intern(yytext)) } -- { $$= getSyntaxId(2, intern(yytext)) } + +meta_try = META_TRY t:meta_stmt i:meta_null c:meta_null f:meta_null + ( META_CATCH META_LPAREN i:META_IDENT META_RPAREN c:meta_stmt ) ? + ( META_FINALLY f:meta_stmt ) ? { $$= newTry(t, i, c, f) } + +meta_null = { $$= null } + +meta_assignOp = META_ASSIGN { $$= null } + | META_ASSIGNADD { $$= Add_symbol } + | META_ASSIGNSUB { $$= Sub_symbol } + | META_ASSIGNMUL { $$= Mul_symbol } + | META_ASSIGNDIV { $$= Div_symbol } + | META_ASSIGNMOD { $$= Mod_symbol } + | META_ASSIGNBITOR { $$= Bitor_symbol } + | META_ASSIGNBITXOR { $$= Bitxor_symbol } + | META_ASSIGNBITAND { $$= Bitand_symbol } + | META_ASSIGNSHLEFT { $$= Shleft_symbol } + | META_ASSIGNSHRIGHT { $$= Shright_symbol } + +meta_switch = META_SWITCH META_LPAREN e:meta_exp META_RPAREN + META_LCB statements:meta_makeMap labels:meta_makeMap + ( META_CASE l:meta_exp META_COLON { map_set(labels, eval(globals, l), makeInteger(map_size(statements))) } + | META_DEFAULT META_COLON { map_set(labels, __default___symbol, makeInteger(map_size(statements))) } + | s:meta_stmt { map_append(statements, s) } + )* + META_RCB { $$= newSwitch(e, labels, statements) } + +meta_cond = c:meta_logor META_QUERY t:meta_exp META_COLON f:meta_cond { $$= newIf(c, t, f) } + | meta_logor + +meta_logor = l:meta_logand + ( META_LOGOR r:meta_logand { l = newBinary(Logor_proto, l, r) } + )* { $$= l } + +meta_logand = l:meta_bitor + ( META_LOGAND r:meta_bitor { l = newBinary(Logand_proto, l, r) } + )* { $$= l } + +meta_bitor = l:meta_bitxor + ( META_BITOR r:meta_bitxor { l = newBinary(Bitor_proto, l, r) } + )* { $$= l } + +meta_bitxor = l:meta_bitand + ( META_BITXOR r:meta_bitand { l = newBinary(Bitxor_proto, l, r) } + )* { $$= l } + +meta_bitand = l:meta_eq + ( META_BITAND r:meta_eq { l = newBinary(Bitand_proto, l, r) } + )* { $$= l } + +meta_eq = l:meta_ineq + ( META_EQUAL r:meta_ineq { l = newBinary(Equal_proto, l, r) } + | META_NOTEQ r:meta_ineq { l = newBinary(Noteq_proto, l, r) } + )* { $$= l } + +meta_ineq = l:meta_shift + ( META_LESS r:meta_shift { l = newBinary(Less_proto, l, r) } + | META_LESSEQ r:meta_shift { l = newBinary(Lesseq_proto, l, r) } + | META_GREATEREQ r:meta_shift { l = newBinary(Greatereq_proto, l, r) } + | META_GREATER r:meta_shift { l = newBinary(Greater_proto, l, r) } + )* { $$= l } + +meta_shift = l:meta_sum + ( META_SHLEFT r:meta_sum { l = newBinary(Shleft_proto, l, r) } + | META_SHRIGHT r:meta_sum { l = newBinary(Shright_proto, l, r) } + )* { $$= l } + +meta_sum = l:meta_prod + ( META_PLUS r:meta_prod { l = newBinary(Add_proto, l, r) } + | META_MINUS r:meta_prod { l = newBinary(Sub_proto, l, r) } + )* { $$= l } + +meta_prod = l:meta_prefix + ( META_MULTI r:meta_prefix { l = newBinary(Mul_proto, l, r) } + | META_DIVIDE r:meta_prefix { l = newBinary(Div_proto, l, r) } + | META_MODULO r:meta_prefix { l = newBinary(Mod_proto, l, r) } + )* { $$= l } + +meta_prefix = META_PLUS n:meta_prefix { $$= n } + | META_NEGATE n:meta_prefix { $$= newUnary(Neg_proto, n) } + | META_TILDE n:meta_prefix { $$= newUnary(Com_proto, n) } + | META_PLING n:meta_prefix { $$= newUnary(Not_proto, n) } + | META_PLUSPLUS n:meta_prefix { $$= newPreIncrement(n) } + | META_MINUSMINUS n:meta_prefix { $$= newPreDecrement(n) } +# | META_BACKTICK n:meta_prefix { $$= newUnary(Quasiquote_proto, n) } +# | META_AT n:meta_prefix { $$= newUnary(Unquote_proto, n) } + | n:meta_postfix { $$= n } + +meta_postfix = i:meta_value + ( META_DOT s:META_IDENT a:meta_argumentList { i = newInvoke(i, s, a) } + | META_DOT s:META_IDENT !meta_assignOp { i = newGetMap(GetMember_proto, i, s) } + | META_LBRAC p:meta_exp META_RBRAC !meta_assignOp { i = newGetMap(GetIndex_proto, i, p) } + | a:meta_argumentList { oop k = map_pop(a); i = newCall(i, a, k) } + | META_PLUSPLUS { i = newPostIncrement(i) } + | META_MINUSMINUS { i = newPostDecrement(i) } + ) * { $$= i } + + +meta_paramList = META_LPAREN m:meta_makeMap + ( i:META_IDENT { map_append(m, i) } + ( META_COMMA i:META_IDENT { map_append(m, i) } + ) * + ) ? + META_RPAREN { $$= m } meta_argumentList = META_LPAREN m:meta_makeMap n:meta_makeMap ( (i:META_IDENT META_COLON { map_set(n, makeInteger(map_size(m)), i) })? e:meta_exp { map_append(m, e) } @@ -2489,64 +2518,85 @@ meta_argumentList = META_LPAREN m:meta_makeMap n:meta_makeMap ) ? META_RPAREN { map_append(m, n); $$ = m } -meta_value = n:META_FLOAT { $$ = newFloat(n) } - | n:meta_integer { $$ = newInteger(n) } - | s:meta_string { $$ = newString(s) } - | s:meta_symbol { $$ = s } - | m:meta_map { $$ = newMap(m) } - | META_NULL { $$ = null } - | i:META_IDENT { $$ = newGetVariable(i) } - | p:meta_paramList e:meta_block { $$ = newFunc(null, p, e, null) } - | META_LPAREN ( i:meta_block | i:meta_exp ) META_RPAREN { $$ = i } +meta_value = n:META_FLOAT { $$= newFloat(n) } + | n:meta_integer { $$= newInteger(n) } + | s:meta_string { $$= newString(s) } + | s:meta_symbol { $$= s } + | m:meta_map { $$= newMap(m) } + | META_NULL { $$= null } + | i:META_IDENT { $$= newGetVariable(i) } + | p:meta_paramList e:meta_block { $$= newFunc(null, p, e, null) } + | META_LPAREN ( i:meta_block | i:meta_exp ) META_RPAREN { $$= i } -meta_string = s:META_STRING -- { $$ = s } +meta_string = s:META_STRING -- { $$= s } -META_STRING = META_DQUOTE < (!META_DQUOTE meta_char)* > META_DQUOTE { $$ = makeString(unescape(yytext)) } +META_STRING = META_DQUOTE < (!META_DQUOTE meta_char)* > META_DQUOTE { $$= makeString(unescape(yytext)) } -meta_char = '\\' . | . +meta_char = '\\' . | . -meta_symbol = META_HASH ( i:META_IDENT { $$ = newSymbol(i) } - | i:meta_string { $$ = newSymbol(intern(get(i, String, value))) } +meta_symbol = META_HASH + ( i:META_IDENT { $$= newSymbol(i) } + | i:meta_string { $$= newSymbol(intern(get(i, String, value))) } ) -meta_map = META_LCB m:meta_makeMap - ( k:meta_key META_COLON v:meta_exp { map_set(m, k, v) } - ( META_COMMA k:meta_key META_COLON v:meta_exp { map_set(m, k, v) } - ) * - ) ? - META_RCB { $$ = m } - | META_LBRAC m:meta_makeMap - ( v:meta_exp { map_append(m, v) } - ( META_COMMA v:meta_exp { map_append(m, v) } - ) * - ) ? - META_RBRAC { $$ = m } - -meta_makeMap = { $$ = makeMap() } +meta_map = META_LCB m:meta_makeMap + ( k:meta_key META_COLON v:meta_exp { map_set(m, k, v) } + ( META_COMMA k:meta_key META_COLON v:meta_exp { map_set(m, k, v) } + ) * + ) ? + META_RCB { $$= m } + | META_LBRAC m:meta_makeMap + ( v:meta_exp { map_append(m, v) } + ( META_COMMA v:meta_exp { map_append(m, v) } + ) * + ) ? + META_RBRAC { $$= m } + +meta_makeMap = { $$= makeMap() } meta_key = META_IDENT | meta_integer -meta_keyword = META_SWITCH | META_CASE | META_DEFAULT | META_DO | META_FOR | META_IN | META_WHILE | META_IF | META_ELSE | META_NULL | META_RETURN | META_BREAK | META_CONTINUE - | META_THROW | META_TRY | META_CATCH | META_FINALLY -# | META_SYNTAX +meta_keyword = META_SWITCH | META_CASE | META_DEFAULT | META_DO | META_FOR | META_IN | META_WHILE | META_IF | META_ELSE | META_NULL | META_RETURN | META_BREAK | META_CONTINUE + | META_THROW | META_TRY | META_CATCH | META_FINALLY +# | META_SYNTAX + +META_IDENT = !meta_keyword < [a-zA-Z_][a-zA-Z0-9_]* > -- { $$= intern(yytext) } -META_IDENT = !meta_keyword < [a-zA-Z_][a-zA-Z0-9_]* > -- { $$ = intern(yytext) } +meta_integer = i:META_INTEGER { $$= i } + | '-' i:meta_integer { $$= makeInteger(-getInteger(i)) } -meta_integer = i:META_INTEGER { $$ = i } - | '-' i:meta_integer { $$ = makeInteger(-getInteger(i)) } +META_INTEGER = '0b' < [01]+ > { $$= makeInteger(strtol(yytext, 0, 2)) } -- + | '0x' < [0-9a-fA-F]+ > { $$= makeInteger(strtol(yytext, 0, 16)) }-- + | '0' < [0-7]+ > { $$= makeInteger(strtol(yytext, 0, 8)) }-- + | < [0-9]+ > { $$= makeInteger(strtol(yytext, 0, 10)) }-- + | META_SQUOTE < (!META_SQUOTE meta_char) > META_SQUOTE { $$= makeInteger(unescape(yytext)[0]) }-- -META_INTEGER = '0b' < [01]+ > { $$ = makeInteger(strtol(yytext, 0, 2)) } -- - | '0x' < [0-9a-fA-F]+ > { $$ = makeInteger(strtol(yytext, 0, 16)) } -- - | '0' < [0-7]+ > { $$ = makeInteger(strtol(yytext, 0, 8)) }-- - | < [0-9]+ > { $$ = makeInteger(strtol(yytext, 0, 10)) } -- - | META_SQUOTE < (!META_SQUOTE meta_char) > META_SQUOTE { $$ = makeInteger(unescape(yytext)[0]) } -- +META_FLOAT = < [-+]* [0-9]+ '.' [0-9]* ('e'[-+]*[0-9]+)? > { $$= makeFloat(strtold(yytext, 0)) } -- + | < [-+]* [0-9]* '.' [0-9]+ ('e'[-+]*[0-9]+)? > { $$= makeFloat(strtold(yytext, 0)) } -- + | < [-+]* [0-9]+ ('e'[-+]*[0-9]+) > { $$= makeFloat(strtold(yytext, 0)) } -- -META_FLOAT = < [-+]* [0-9]+ '.' [0-9]* ('e'[-+]*[0-9]+)? > { $$ = makeFloat(strtold(yytext, 0)) } -- - | < [-+]* [0-9]* '.' [0-9]+ ('e'[-+]*[0-9]+)? > { $$ = makeFloat(strtold(yytext, 0)) } -- - | < [-+]* [0-9]+ ('e'[-+]*[0-9]+) > { $$ = makeFloat(strtold(yytext, 0)) } -- +#--------------------------------------------- Meta operator ----------------------------------------------# -#META_FUN = 'fun' ![a-zA-Z0-9_] -- -#META_SYNTAX = 'syntax' ![a-zA-Z0-9_] -- +MO_OPERATION = META_BACKTICK ( MO_CONSTANT c:constant { $$= newUnary(Quasiquote_proto, c) } + | MO_STRING s:stringLiteral { $$= newUnary(Quasiquote_proto, s) } + | MO_EXPRESSION e:expression { $$= newUnary(Quasiquote_proto, e) } + | MO_FUN f:functionDefinition { $$= newUnary(Quasiquote_proto, f) } + | MO_DECLARATION d:declaration { $$= newUnary(Quasiquote_proto, d) } + | MO_STATEMENT s:statement { $$= newUnary(Quasiquote_proto, s) } + ) + +MO_CONSTANT = 'constant' ![(a-zA-Z0-9_] -- +MO_STRING = 'string' ![(a-zA-Z0-9_] -- +MO_EXPRESSION = 'expression' ![(a-zA-Z0-9_] -- +MO_FUN = 'fun' ![(a-zA-Z0-9_] -- +MO_DECLARATION = 'declaration' ![(a-zA-Z0-9_] -- +MO_STATEMENT = 'statement' ![(a-zA-Z0-9_] -- + + +#--------------------------------------------- Meta rules ----------------------------------------------# + +#META_FUN = 'fun' ![a-zA-Z0-9_] -- +#META_SYNTAX = 'syntax' ![a-zA-Z0-9_] -- META_VAR = 'var' ![a-zA-Z0-9_] -- META_SWITCH = 'switch' ![a-zA-Z0-9_] -- META_CASE = 'case' ![a-zA-Z0-9_] -- @@ -2557,7 +2607,7 @@ META_IN = 'in' ![a-zA-Z0-9_] -- META_WHILE = 'while' ![a-zA-Z0-9_] -- META_IF = 'if' ![a-zA-Z0-9_] -- META_ELSE = 'else' ![a-zA-Z0-9_] -- -META_NULL = 'null' ![a-zA-Z0-9_] -- +META_NULL = ('null'|'nil') ![a-zA-Z0-9_] -- META_RETURN = 'return' ![a-zA-Z0-9_] -- META_BREAK = 'break' ![a-zA-Z0-9_] -- META_CONTINUE = 'continue' ![a-zA-Z0-9_] -- @@ -2606,7 +2656,7 @@ META_COLON = ':' -- META_SEMICOLON = ';' -- META_COMMA = ',' -- META_DOT = '.' -- -#META_BACKTICK = '`' -- +META_BACKTICK = '`' -- META_AT = '@' -- META_LCB = '{' -- META_RCB = '}' -- @@ -2982,11 +3032,15 @@ oop eval(oop scope, oop ast) } return map; } -#if 0 + case t_Quote: { + oop obj = map_get(ast, rhs_symbol); + return obj; + } case t_Quasiquote: { oop obj = map_get(ast, rhs_symbol); - return expandUnquotes(scope, obj); + return treeCopyUnquoting(scope, obj); } +#if 0 case t_Unquote: { runtimeError("@ outside of `"); } @@ -3817,6 +3871,8 @@ void outputNode(oop node) case Symbol: outputText(get(node, Symbol, name)); return; + case Function: + return; default: fprintf(stderr, "\noutputNode: unknown node type %i\n", getType(node)); abort(); @@ -4225,9 +4281,12 @@ void outputTree(oop node, int depth) CASE(float) OUT(text); break; - CASE(string) + CASE(stringLiteral) OUT(text); break; + CASE(string) + OUT(value); + break; CASE(char) OUT(value); break; @@ -4760,6 +4819,9 @@ void outputTree(oop node, int depth) CASE(GetVariable) OUT(key) break; + CASE(Quote) + OUT(rhs); + break; /** TODO * CASE(Quasiquote) * PRINT(Quasiquote);