diff --git a/ccmeta.leg b/ccmeta.leg index 2f17324..23b188f 100644 --- a/ccmeta.leg +++ b/ccmeta.leg @@ -3,7 +3,7 @@ # Copyright (c) 2016-2021 Ian Piumarta and other contributors (see AUTHORS) # All rights reserved (see LICENSE) # -# Last edited: 2021-07-06 16:09:02 by piumarta on DESKTOP-LTPREOB +# Last edited: 2021-07-12 18:54:53 by piumarta on DESKTOP-LTPREOB %{ /* compile: leg -o ccmeta.c ccmeta.leg @@ -29,10 +29,11 @@ _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(Quasiquote) _DO(Unquote) */ \ _DO(Comment) _DO(Token) \ + _DO(C_declaration) \ _DO(C_if) _DO(C_int) _DO(C_float) _DO(C_char) _DO(C_id) _DO(C_while) _DO(C_do) _DO(C_for) \ - _DO(C_binary) + _DO(C_binary) typedef enum { t_UNDEFINED=0, @@ -85,7 +86,7 @@ oop globals= 0; _DO(comment) \ _DO(text) _DO(if) _DO(lparen) _DO(rparen) _DO(else) _DO(identifier) _DO(semicolon) _DO(while) \ _DO(do) _DO(for) _DO(initExpr) _DO(condExpr) _DO(incrExpr) _DO(firstSemi) _DO(secondSemi) \ - _DO(binary) + _DO(binary) _DO(specifiers) _DO(declarators) #define _DO(NAME) oop NAME##_symbol; @@ -259,29 +260,32 @@ oop new_C_if(oop ifTok, oop lParen, oop condition, oop rParen, oop consequent, o return obj; } -oop new_C_while (oop whileTok, oop lParen, oop expression, oop rParen, oop statement) { +oop new_C_while(oop whileTok, oop lParen, oop expression, oop rParen, oop statement) +{ oop object = newObject(C_while_proto); - map_set(object, while_symbol, whileTok); - map_set(object, lparen_symbol, lParen); + map_set(object, while_symbol, whileTok); + map_set(object, lparen_symbol, lParen); map_set(object, expression_symbol, expression); map_set(object, rparen_symbol, rParen); map_set(object, statements_symbol, statement); return object; } -oop new_C_do (oop doTok, oop statement, oop whileTok, oop lParen, oop expression, oop rParen, oop semicolon) { +oop new_C_do(oop doTok, oop statement, oop whileTok, oop lParen, oop expression, oop rParen, oop semicolon) +{ oop object = newObject(C_do_proto); map_set(object, do_symbol, doTok); map_set(object, statements_symbol, statement); map_set(object, while_symbol, whileTok); - map_set(object, lparen_symbol, lParen); + map_set(object, lparen_symbol, lParen); map_set(object, expression_symbol, expression); map_set(object, rparen_symbol, rParen); map_set(object, semicolon_symbol, semicolon); - return object; + return object; } - -oop new_C_for(oop forTok, oop lParen, oop initExpr, oop semicolon1, oop condExpr, oop semicolon2, oop incrExpr, oop rParen, oop statement) { + +oop new_C_for(oop forTok, oop lParen, oop initExpr, oop semicolon1, oop condExpr, oop semicolon2, oop incrExpr, oop rParen, oop statement) +{ oop object = newObject(C_for_proto); map_set(object, for_symbol, forTok); map_set(object, lparen_symbol, lParen); @@ -313,15 +317,15 @@ oop newSymbol(oop name) return symbol; } -oop new_C_int(int value) { +oop new_C_int(char *text) { oop object = newObject(C_int_proto); - map_set(object, value_symbol, makeInteger(value)); + map_set(object, text_symbol, makeString(text)); return object; } -oop new_C_float(float value) { +oop new_C_float(char *text) { oop object = newObject(C_float_proto); - map_set(object, value_symbol, makeFloat(value)); + map_set(object, text_symbol, makeString(text)); return object; } @@ -611,6 +615,19 @@ oop new_C_id(char* id) { return object; } +oop new_C_declaration(oop specifiers, oop declarators, oop semicolon) { + oop object = newObject(C_declaration_proto); + map_set(object, specifiers_symbol, specifiers); + map_set(object, declarators_symbol, declarators); + map_set(object, semicolon_symbol, semicolon); + return object; +} + +void C_declarationBegin(void) {} +int C_declarationAbort(void) { return 0; } +void C_declarationEnd(void) {} + + #define YY_INPUT(buf, result, max_size) \ { \ @@ -669,6 +686,40 @@ void setComment(oop ast, oop comment) map_set(ast, comment_symbol, comment); } + +OopStack listOfLists= BUFFER_INITIALISER; +oop currentList= 0; + +void listBegin(void) +{ + OopStack_push(&listOfLists, currentList); + currentList= makeMap(); +} + +void listAppend(oop obj) +{ + assert(currentList); + map_append(currentList, obj); +} + +oop listEnd(void) +{ + assert(currentList); + oop list= currentList; + currentList= OopStack_pop(&listOfLists); + return list; +} + +oop listEmpty(void) +{ + return makeMap(); +} + +void declarationTypedef(void) +{ + printf("DECLARATION TYPEDEF\n"); +} + %} @@ -680,7 +731,7 @@ error = EOL* < (!EOL .)* EOL* (!EOL .)* > &{ error(yytext), 1 # 6.4.2.1 -idOpt = id #| TODO : End parsing | {$$=0} +idOpt = id #| TODO : End parsing | {$$=0} id = { $$= new_C_id(yytext) } - ID = #| TODO : &{ !intern(yytext)->isKeyword } @@ -707,10 +758,10 @@ hexQuad = hexadecimalDigit hexadecimalDigit hexadecimalDigit hexadecimalDigit # 6.4.4 -constant = characterConstant - | floatingConstant - | integerConstant - +constant = characterConstant + | floatingConstant + | integerConstant + # 6.4.4.1 @@ -719,7 +770,7 @@ integerConstant = < ( hexadecimalConstant | octalConstant | binaryConstant &{gnu} | decimalConstant - ) integerSuffix? > { $$ = new_C_int(atoi(yytext)); } - + ) integerSuffix? > { $$ = new_C_int(yytext); } - decimalConstant = [1-9][0-9]* @@ -741,7 +792,7 @@ imaginarySuffix = [ij] # 6.4.4.2 -floatingConstant = <( decimalFloatingConstant | hexadecimalFloatingConstant )> { $$ = new_C_float(atof(yytext)); } - +floatingConstant = <( decimalFloatingConstant | hexadecimalFloatingConstant )> { $$ = new_C_float(yytext); } - decimalFloatingConstant = fractionalConstant exponentPart? floatingSuffix? @@ -769,7 +820,7 @@ floatingSuffix = [fFlL] imaginarySuffix? # 6.4.4.4 characterConstant = < "'" cCharSequence "'" > { $$ = new_C_char(yytext) } - - | < "L'" cCharSequence "'" > { $$ = new_C_char(yytext) } - + | < "L'" cCharSequence "'" > { $$ = new_C_char(yytext) } - cCharSequence = ( escapeSequence | !EOL [^\'\\] )* @@ -954,26 +1005,27 @@ hexadecimalEscapeSequence = '\\x' hexadecimalDigit+ #| #|# 6.7 #| -#|declaration = @{ declarationBegin() } -#| ( s:declarationSpecifiers -#| d:initDeclaratorListOpt -#| t:SEMI { $$= newDeclaration(s, d, t) } -#| @{ declarationEnd() } -#| | -#| &{ declarationAbort() } -#| ) -#| -#|declarationSpecifiers = @{ int specified= 0 } { listBegin() } -#| ( s:storageClassSpecifier { listAppend(s) } -#| | s:typeSpecifier @{ specified++ } { listAppend(s) } -#| | s:typedefName &{ !specified++ } { listAppend(s) } -#| | s:typeQualifier { listAppend(s) } +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) } +#| | s:typedefName &{ !specified++ } { listAppend(s) } +#| | s:typeQualifier { listAppend(s) } #| | s:functionSpecifier { listAppend(s) } -#| )+ { $$= listEnd() } -#| | &{gnu} { $$= 0 } -#| + )+ { $$= listEnd() } + | &{gnu} { $$= listEmpty() } + #|initDeclaratorListOpt = initDeclaratorList | { $$= 0 } -#| +initDeclaratorListOpt = { $$= listEmpty() } + #|initDeclaratorList = d:initDeclarator { listWith(d) } #| ( c:COMMA d:initDeclarator { listAppend2(c, d) } #| )* { $$= listEnd() } @@ -983,9 +1035,9 @@ hexadecimalEscapeSequence = '\\x' hexadecimalDigit+ #| )? { $$= d } #| #|# 6.7.1 -#| -#|storageClassSpecifier = TYPEDEF @{ declarationTypedef() } -#| | AUTO + +storageClassSpecifier = TYPEDEF @{ declarationTypedef() } + | AUTO #| | parameterStorageClassSpecifier #| | functionStorageClassSpecifier #| @@ -994,8 +1046,8 @@ hexadecimalEscapeSequence = '\\x' hexadecimalDigit+ #|functionStorageClassSpecifier = EXTERN | STATIC #| #|# 6.7.2 -#| -#|typeSpecifier = VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | BOOL | COMPLEX + +typeSpecifier = VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | BOOL | COMPLEX #| | structOrUnionSpecifier #| | enumSpecifier #| # Any list of specifiers and qualifiers at the start of a declaration may contain attribute specifiers @@ -1269,9 +1321,8 @@ hexadecimalEscapeSequence = '\\x' hexadecimalDigit+ #| externalDeclaration = { yylval = newComment(yytext); } | ( SEMI &{gnu} - | c:constant { yylval = c; } #| TODO - | i:idOpt { yylval = i; } #| TODO -#| | declaration + | c:constant { yylval = c; } #################| TODO + | declaration #| | functionDefinition #| | meta | &. &{ errmsg= "declaration expected" } error @@ -2579,33 +2630,29 @@ void outputText(char *text) ocol += strlen(text); } -void outputInt(int value) { - printf("%i", value); - char *toString = malloc(sizeof(value)); - sprintf(toString,"%d", value); - ocol += strlen(toString); +void outputInt(int_t value) +{ + ocol += printf(FMT_I, value); } -void outputFloat(float value) { - printf("%f", value); - char *toString = malloc(sizeof(value)); - sprintf(toString,"%f", value); - ocol += strlen(toString); +void outputFloat(flt_t value) +{ + ocol += printf(FMT_F, value); } void outputNode(oop node) { if (!node) return; - switch (node->type) { - case Undefined: + switch (getType(node)) { + case Undefined: return; - case String: - outputText(get(node, String, value)); + case String: + outputText(get(node, String, value)); return; - case Map: + case Map: break; - case Integer: - outputInt(getInteger(node)); + case Integer: + outputInt(getInteger(node)); return; case Float: outputFloat(getFloat(node)); @@ -2614,74 +2661,89 @@ void outputNode(oop node) outputText(get(node, Symbol, name)); return; default: - fprintf(stderr, "\noutputNode: unknown node type %i\n", node->type); + fprintf(stderr, "\noutputNode: unknown node type %i\n", getType(node)); abort(); } assert(is(Map, node)); oop proto= map_get(node, __proto___symbol); - if (null == proto) return; + if (null == proto) { // assume this is just a list of nodes + size_t size= map_size(node); + for (size_t i= 0; i < size; ++i) { + if (!map_hasIntegerKey(node, i)) break; + outputNode(get(node, Map, elements)[i].value); + } + return; + } // proto_number is the enum version of the proto symbol proto_t proto_number= get(map_get(proto, __name___symbol), Symbol, prototype); switch (proto_number) { - case t_Comment: - outputNode(map_get(node, text_symbol)); - break; - case t_Token: - outputNode(map_get(node, name_symbol)); - break; - case t_C_int: - outputNode(map_get(node, value_symbol)); - break; - case t_C_float: - outputNode(map_get(node, value_symbol)); - break; - case t_C_char: - outputNode(map_get(node, value_symbol)); - break; - case t_C_id: - outputNode(map_get(node, identifier_symbol)); - break; - case t_C_if: - outputNode(map_get(node, if_symbol)); - outputNode(map_get(node, lparen_symbol)); - outputNode(map_get(node, condition_symbol)); - outputNode(map_get(node, rparen_symbol)); - outputNode(map_get(node, consequent_symbol)); - outputNode(map_get(node, else_symbol)); // null if no else clause - outputNode(map_get(node, alternate_symbol)); // null if no else clause - break; - case t_C_while: - outputNode(map_get(node, while_symbol)); - outputNode(map_get(node, lparen_symbol)); - outputNode(map_get(node, expression_symbol)); - outputNode(map_get(node, rparen_symbol)); - outputNode(map_get(node, statements_symbol)); - break; - case t_C_do: - outputNode(map_get(node, do_symbol)); - outputNode(map_get(node, statements_symbol)); - outputNode(map_get(node, while_symbol)); - outputNode(map_get(node, lparen_symbol)); - outputNode(map_get(node, expression_symbol)); - outputNode(map_get(node, rparen_symbol)); - outputNode(map_get(node, semicolon_symbol)); - break; - case t_C_for: - outputNode(map_get(node, for_symbol)); - outputNode(map_get(node, lparen_symbol)); - outputNode(map_get(node, initExpr_symbol)); - outputNode(map_get(node, firstSemi_symbol)); - outputNode(map_get(node, condExpr_symbol)); - outputNode(map_get(node, secondSemi_symbol)); - outputNode(map_get(node, incrExpr_symbol)); - outputNode(map_get(node, rparen_symbol)); - outputNode(map_get(node, statements_symbol)); - break; - case t_C_binary: - outputNode(map_get(node, lhs_symbol)); - outputNode(map_get(node, binary_symbol)); - outputNode(map_get(node, rhs_symbol)); - break; + case t_Comment: + outputNode(map_get(node, text_symbol)); + break; + case t_Token: + outputNode(map_get(node, text_symbol)); + break; + case t_C_int: + outputNode(map_get(node, text_symbol)); + break; + case t_C_float: + outputNode(map_get(node, text_symbol)); + break; + case t_C_char: + outputNode(map_get(node, value_symbol)); + break; + case t_C_id: + outputNode(map_get(node, identifier_symbol)); + break; + case t_C_declaration: + outputNode(map_get(node, specifiers_symbol)); + outputNode(map_get(node, declarators_symbol)); + outputNode(map_get(node, semicolon_symbol)); + break; + case t_C_if: + outputNode(map_get(node, if_symbol)); + outputNode(map_get(node, lparen_symbol)); + outputNode(map_get(node, condition_symbol)); + outputNode(map_get(node, rparen_symbol)); + outputNode(map_get(node, consequent_symbol)); + outputNode(map_get(node, else_symbol)); // null if no else clause + outputNode(map_get(node, alternate_symbol)); // null if no else clause + break; + case t_C_while: + outputNode(map_get(node, while_symbol)); + outputNode(map_get(node, lparen_symbol)); + outputNode(map_get(node, expression_symbol)); + outputNode(map_get(node, rparen_symbol)); + outputNode(map_get(node, statements_symbol)); + break; + case t_C_do: + outputNode(map_get(node, do_symbol)); + outputNode(map_get(node, statements_symbol)); + outputNode(map_get(node, while_symbol)); + outputNode(map_get(node, lparen_symbol)); + outputNode(map_get(node, expression_symbol)); + outputNode(map_get(node, rparen_symbol)); + outputNode(map_get(node, semicolon_symbol)); + break; + case t_C_for: + outputNode(map_get(node, for_symbol)); + outputNode(map_get(node, lparen_symbol)); + outputNode(map_get(node, initExpr_symbol)); + outputNode(map_get(node, firstSemi_symbol)); + outputNode(map_get(node, condExpr_symbol)); + outputNode(map_get(node, secondSemi_symbol)); + outputNode(map_get(node, incrExpr_symbol)); + outputNode(map_get(node, rparen_symbol)); + outputNode(map_get(node, statements_symbol)); + break; + case t_C_binary: + outputNode(map_get(node, lhs_symbol)); + outputNode(map_get(node, binary_symbol)); + outputNode(map_get(node, rhs_symbol)); + break; + default: + printf("I cannot print a node with proto_number %i\n", proto_number); + exit(0); } #if 0 while (orow < node->row) { printf("\n"); ++orow; ocol= 0; }