diff options
Diffstat (limited to 'src/loadcolm.cc')
-rw-r--r-- | src/loadcolm.cc | 2341 |
1 files changed, 2341 insertions, 0 deletions
diff --git a/src/loadcolm.cc b/src/loadcolm.cc new file mode 100644 index 0000000..6bdac1c --- /dev/null +++ b/src/loadcolm.cc @@ -0,0 +1,2341 @@ +/* + * Copyright 2006-2012 Adrian Thurston <thurston@complang.org> + */ + +/* This file is part of Colm. + * + * Colm is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Colm is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Colm; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <iostream> +#include <errno.h> + +#include "parser.h" +#include "config.h" +#include "avltree.h" +#include "parsedata.h" +#include "parser.h" +#include "global.h" +#include "input.h" +#include "loadcolm.h" +#include "if2.h" +#include "colm/colm.h" + +extern RuntimeData colm_object; + +InputLoc::InputLoc( colm_location *pcloc ) +{ + if ( pcloc != 0 ) { + fileName = pcloc->name; + line = pcloc->line; + col = pcloc->column; + } + else { + fileName = 0; + line = -1; + col = -1; + } +} + + +String unescape( const String &s ) +{ + String out( String::Fresh(), s.length() ); + char *d = out.data; + + for ( int i = 0; i < s.length(); ) { + if ( s[i] == '\\' ) { + switch ( s[i+1] ) { + case '0': *d++ = '\0'; break; + case 'a': *d++ = '\a'; break; + case 'b': *d++ = '\b'; break; + case 't': *d++ = '\t'; break; + case 'n': *d++ = '\n'; break; + case 'v': *d++ = '\v'; break; + case 'f': *d++ = '\f'; break; + case 'r': *d++ = '\r'; break; + default: *d++ = s[i+1]; break; + } + i += 2; + } + else { + *d++ = s[i]; + i += 1; + } + } + out.chop( d - out.data ); + return out; +} + + +struct LoadColm +: + public BaseParser +{ + LoadColm( Compiler *pd, const char *inputFileName ) + : + BaseParser( pd ), + inputFileName( inputFileName ) + {} + + const char *inputFileName; + + Literal *walkLexRangeLit( lex_range_lit lexRangeLit ) + { + Literal *literal = 0; + switch ( lexRangeLit.prodName() ) { + case lex_range_lit::_Lit: { + String lit = lexRangeLit.lex_lit().data(); + literal = Literal::cons( lexRangeLit.lex_lit().loc(), lit, Literal::LitString ); + break; + } + case lex_range_lit::_Number: { + String num = lexRangeLit.lex_num().text().c_str(); + literal = Literal::cons( lexRangeLit.lex_num().loc(), num, Literal::Number ); + break; + }} + return literal; + } + + LexFactor *walkLexFactor( lex_factor lexFactor ) + { + LexFactor *factor = 0; + switch ( lexFactor.prodName() ) { + case lex_factor::_Literal: { + String litString = lexFactor.lex_lit().data(); + Literal *literal = Literal::cons( lexFactor.lex_lit().loc(), + litString, Literal::LitString ); + factor = LexFactor::cons( literal ); + break; + } + case lex_factor::_Id: { + String id = lexFactor.lex_id().data(); + factor = lexRlFactorName( id, lexFactor.lex_id().loc() ); + break; + } + case lex_factor::_Range: { + Literal *low = walkLexRangeLit( lexFactor.Low() ); + Literal *high = walkLexRangeLit( lexFactor.High() ); + + Range *range = Range::cons( low, high ); + factor = LexFactor::cons( range ); + break; + } + case lex_factor::_PosOrBlock: { + ReOrBlock *block = walkRegOrData( lexFactor.reg_or_data() ); + factor = LexFactor::cons( ReItem::cons( block, ReItem::OrBlock ) ); + break; + } + case lex_factor::_NegOrBlock: { + ReOrBlock *block = walkRegOrData( lexFactor.reg_or_data() ); + factor = LexFactor::cons( ReItem::cons( block, ReItem::NegOrBlock ) ); + break; + } + case lex_factor::_Number: { + String number = lexFactor.lex_uint().text().c_str(); + factor = LexFactor::cons( Literal::cons( lexFactor.lex_uint().loc(), + number, Literal::Number ) ); + break; + } + case lex_factor::_Hex: { + String number = lexFactor.lex_hex().text().c_str(); + factor = LexFactor::cons( Literal::cons( lexFactor.lex_hex().loc(), + number, Literal::Number ) ); + break; + } + case lex_factor::_Paren: { + lex_expr LexExpr = lexFactor.lex_expr(); + LexExpression *expr = walkLexExpr( LexExpr ); + LexJoin *join = LexJoin::cons( expr ); + factor = LexFactor::cons( join ); + break; + }} + return factor; + } + + LexFactorAug *walkLexFactorAug( lex_factor_rep LexFactorRepTree ) + { + LexFactorRep *factorRep = walkLexFactorRep( LexFactorRepTree ); + return LexFactorAug::cons( factorRep ); + } + + LangExpr *walkCodeExpr( code_expr codeExpr ) + { + LangExpr *expr = 0; + LangExpr *relational = walkCodeRelational( codeExpr.code_relational() ); + + switch ( codeExpr.prodName() ) { + case code_expr::_AmpAmp: { + LangExpr *left = walkCodeExpr( codeExpr._code_expr() ); + + InputLoc loc = codeExpr.AMPAMP().loc(); + expr = LangExpr::cons( loc, left, OP_LogicalAnd, relational ); + break; + } + case code_expr::_BarBar: { + LangExpr *left = walkCodeExpr( codeExpr._code_expr() ); + + InputLoc loc = codeExpr.BARBAR().loc(); + expr = LangExpr::cons( loc, left, OP_LogicalOr, relational ); + break; + } + case code_expr::_Base: { + expr = relational; + break; + }} + return expr; + } + + LangStmt *walkStatement( statement Statement ) + { + LangStmt *stmt = 0; + switch ( Statement.prodName() ) { + case statement::_Print: { + print_stmt printStmt = Statement.print_stmt(); + stmt = walkPrintStmt( printStmt ); + break; + } + case statement::_Expr: { + expr_stmt exprStmt = Statement.expr_stmt(); + stmt = walkExprStmt( exprStmt ); + break; + } + case statement::_VarDef: { + ObjectField *objField = walkVarDef( Statement.var_def() ); + LangExpr *expr = walkOptDefInit( Statement.opt_def_init() ); + stmt = varDef( objField, expr, LangStmt::AssignType ); + break; + } + case statement::_For: { + pushScope(); + + String forDecl = Statement.id().text().c_str(); + TypeRef *typeRef = walkTypeRef( Statement.type_ref() ); + StmtList *stmtList = walkBlockOrSingle( Statement.block_or_single() ); + + IterCall *iterCall = walkIterCall( Statement.iter_call() ); + + stmt = forScope( Statement.id().loc(), forDecl, + curScope, typeRef, iterCall, stmtList ); + + popScope(); + break; + } + case statement::_If: { + pushScope(); + + LangExpr *expr = walkCodeExpr( Statement.code_expr() ); + StmtList *stmtList = walkBlockOrSingle( Statement.block_or_single() ); + + popScope(); + + LangStmt *elsifList = walkElsifList( Statement.elsif_list() ); + stmt = LangStmt::cons( LangStmt::IfType, expr, stmtList, elsifList ); + break; + } + case statement::_While: { + pushScope(); + LangExpr *expr = walkCodeExpr( Statement.code_expr() ); + StmtList *stmtList = walkBlockOrSingle( Statement.block_or_single() ); + stmt = LangStmt::cons( LangStmt::WhileType, expr, stmtList ); + popScope(); + break; + } + case statement::_LhsVarRef: { + LangVarRef *varRef = walkVarRef( Statement.var_ref() ); + LangExpr *expr = walkCodeExpr( Statement.code_expr() ); + stmt = LangStmt::cons( varRef->loc, LangStmt::AssignType, varRef, expr ); + break; + } + case statement::_Yield: { + LangVarRef *varRef = walkVarRef( Statement.var_ref() ); + stmt = LangStmt::cons( LangStmt::YieldType, varRef ); + break; + } + case statement::_Return: { + LangExpr *expr = walkCodeExpr( Statement.code_expr() ); + stmt = LangStmt::cons( Statement.loc(), LangStmt::ReturnType, expr ); + break; + } + case statement::_Break: { + stmt = LangStmt::cons( LangStmt::BreakType ); + break; + } + case statement::_Reject: { + stmt = LangStmt::cons( Statement.REJECT().loc(), LangStmt::RejectType ); + break; + }} + return stmt; + } + + StmtList *walkLangStmtList( lang_stmt_list langStmtList ) + { + StmtList *retList = new StmtList; + _repeat_statement stmtList = langStmtList.StmtList(); + + /* Walk the list of items. */ + while ( !stmtList.end() ) { + statement Statement = stmtList.value(); + LangStmt *stmt = walkStatement( Statement ); + if ( stmt != 0 ) + retList->append( stmt ); + stmtList = stmtList.next(); + } + + require_pattern require = langStmtList.opt_require_stmt().require_pattern(); + if ( require != 0 ) { + pushScope(); + + LangVarRef *varRef = walkVarRef( require.var_ref() ); + PatternItemList *list = walkPattern( require.pattern(), varRef ); + LangExpr *expr = match( require.REQUIRE().loc(), varRef, list ); + + StmtList *reqList = walkLangStmtList( langStmtList.opt_require_stmt().lang_stmt_list() ); + + LangStmt *stmt = LangStmt::cons( LangStmt::IfType, expr, reqList, 0 ); + + popScope(); + + retList->append( stmt ); + } + + return retList; + } + + void walkTokenDef( token_def TokenDef ) + { + String name = TokenDef.id().data(); + + bool niLeft = walkNoIgnoreLeft( TokenDef.no_ignore_left() ); + bool niRight = walkNoIgnoreRight( TokenDef.no_ignore_right() ); + + ObjectDef *objectDef = walkVarDefList( TokenDef.VarDefList() ); + objectDef->name = name; + + LexJoin *join = 0; + if ( TokenDef.opt_lex_expr().lex_expr() != 0 ) { + LexExpression *expr = walkLexExpr( TokenDef.opt_lex_expr().lex_expr() ); + join = LexJoin::cons( expr ); + } + + CodeBlock *translate = walkOptTranslate( TokenDef.opt_translate() ); + + defineToken( TokenDef.id().loc(), name, join, objectDef, + translate, false, niLeft, niRight ); + } + + void walkIgnoreCollector( ic_def IgnoreCollector ) + { + String id = IgnoreCollector.id().data(); + zeroDef( IgnoreCollector.id().loc(), id ); + } + + String walkOptId( opt_id optId ) + { + String name; + if ( optId.prodName() == opt_id::_Id ) + name = optId.id().data(); + return name; + } + + ObjectDef *walkVarDefList( _repeat_var_def varDefList ) + { + ObjectDef *objectDef = ObjectDef::cons( ObjectDef::UserType, + String(), pd->nextObjectId++ ); + + while ( !varDefList.end() ) { + ObjectField *varDef = walkVarDef( varDefList.value() ); + objVarDef( objectDef, varDef ); + varDefList = varDefList.next(); + } + + return objectDef; + } + + void walkPreEof( pre_eof_def PreEofDef ) + { + ObjectDef *localFrame = blockOpen(); + StmtList *stmtList = walkLangStmtList( PreEofDef.lang_stmt_list() ); + preEof( PreEofDef.PREEOF().loc(), stmtList, localFrame ); + blockClose(); + } + + void walkIgnoreDef( ignore_def IgnoreDef ) + { + String name = walkOptId( IgnoreDef.opt_id() ); + ObjectDef *objectDef = ObjectDef::cons( ObjectDef::UserType, + name, pd->nextObjectId++ ); + + LexJoin *join = 0; + if ( IgnoreDef.opt_lex_expr().lex_expr() != 0 ) { + LexExpression *expr = walkLexExpr( IgnoreDef.opt_lex_expr().lex_expr() ); + join = LexJoin::cons( expr ); + } + + defineToken( IgnoreDef.IGNORE().loc(), name, join, objectDef, + 0, true, false, false ); + } + + LangExpr *walkCodeMultiplicitive( code_multiplicitive mult ) + { + LangExpr *expr = 0; + LangExpr *right = walkCodeUnary( mult.code_unary() ); + switch ( mult.prodName() ) { + case code_multiplicitive::_Star: { + LangExpr *left = walkCodeMultiplicitive( mult._code_multiplicitive() ); + expr = LangExpr::cons( mult.STAR().loc(), left, '*', right ); + break; + } + case code_multiplicitive::_Fslash: { + LangExpr *left = walkCodeMultiplicitive( mult._code_multiplicitive() ); + expr = LangExpr::cons( mult.FSLASH().loc(), left, '/', right ); + break; + } + case code_multiplicitive::_Base: { + expr = right; + break; + }} + return expr; + } + + PatternItemList *walkPatternElTypeOrLit( pattern_el_lel typeOrLit, + LangVarRef *patternVarRef ) + { + NamespaceQual *nspaceQual = walkRegionQual( typeOrLit.region_qual() ); + RepeatType repeatType = walkOptRepeat( typeOrLit.opt_repeat() ); + + PatternItemList *list = 0; + switch ( typeOrLit.prodName() ) { + case pattern_el_lel::_Id: { + String id = typeOrLit.id().data(); + list = patternElNamed( typeOrLit.id().loc(), patternVarRef, + nspaceQual, id, repeatType ); + break; + } + case pattern_el_lel::_Lit: { + String lit = typeOrLit.backtick_lit().data(); + list = patternElType( typeOrLit.backtick_lit().loc(), patternVarRef, + nspaceQual, lit, repeatType ); + break; + }} + + return list; + } + + LangVarRef *walkOptLabel( opt_label optLabel ) + { + LangVarRef *varRef = 0; + if ( optLabel.prodName() == opt_label::_Id ) { + String id = optLabel.id().data(); + varRef = LangVarRef::cons( optLabel.id().loc(), + curContext(), curScope, id ); + } + return varRef; + } + + PatternItemList *walkPatternEl( pattern_el patternEl, LangVarRef *patternVarRef ) + { + PatternItemList *list = 0; + switch ( patternEl.prodName() ) { + case pattern_el::_Dq: { + list = walkLitpatElList( patternEl.LitpatElList(), + patternEl.dq_lit_term().CONS_DQ_NL(), patternVarRef ); + break; + } + case pattern_el::_Sq: { + list = walkPatSqConsDataList( patternEl.SqConsDataList(), + patternEl.sq_lit_term().CONS_SQ_NL() ); + break; + } + case pattern_el::_Tilde: { + String patternData = patternEl.opt_tilde_data().text().c_str(); + patternData += '\n'; + PatternItem *patternItem = PatternItem::cons( PatternItem::InputTextForm, + patternEl.opt_tilde_data().loc(), patternData ); + list = PatternItemList::cons( patternItem ); + break; + } + case pattern_el::_PatternEl: { + PatternItemList *typeOrLitList = walkPatternElTypeOrLit( + patternEl.pattern_el_lel(), patternVarRef ); + LangVarRef *varRef = walkOptLabel( patternEl.opt_label() ); + list = consPatternEl( varRef, typeOrLitList ); + break; + }} + return list; + } + + PatternItemList *walkLitpatEl( litpat_el litpatEl, LangVarRef *patternVarRef ) + { + PatternItemList *list = 0; + switch ( litpatEl.prodName() ) { + case litpat_el::_ConsData: { + String consData = unescape( litpatEl.dq_cons_data().text().c_str() ); + PatternItem *patternItem = PatternItem::cons( PatternItem::InputTextForm, + litpatEl.dq_cons_data().loc(), consData ); + list = PatternItemList::cons( patternItem ); + break; + } + case litpat_el::_SubList: { + list = walkPatternElList( litpatEl.PatternElList(), patternVarRef ); + break; + }} + return list; + } + + PatternItemList *walkPatSqConsDataList( _repeat_sq_cons_data sqConsDataList, CONS_SQ_NL Nl ) + { + PatternItemList *list = new PatternItemList; + while ( !sqConsDataList.end() ) { + String consData = unescape( sqConsDataList.value().text().c_str() ); + PatternItem *patternItem = PatternItem::cons( PatternItem::InputTextForm, + sqConsDataList.value().loc(), consData ); + PatternItemList *tail = PatternItemList::cons( patternItem ); + list = patListConcat( list, tail ); + + sqConsDataList = sqConsDataList.next(); + } + + if ( Nl != 0 ) { + String nl = unescape( Nl.data() ); + PatternItem *patternItem = PatternItem::cons( PatternItem::InputTextForm, + Nl.loc(), nl ); + PatternItemList *term = PatternItemList::cons( patternItem ); + list = patListConcat( list, term ); + } + + return list; + } + + ConsItemList *walkConsSqConsDataList( _repeat_sq_cons_data sqConsDataList, CONS_SQ_NL Nl ) + { + ConsItemList *list = new ConsItemList; + while ( !sqConsDataList.end() ) { + String consData = unescape( sqConsDataList.value().text().c_str() ); + ConsItem *consItem = ConsItem::cons( + sqConsDataList.value().loc(), ConsItem::InputText, consData ); + ConsItemList *tail = ConsItemList::cons( consItem ); + list = consListConcat( list, tail ); + + sqConsDataList = sqConsDataList.next(); + } + + if ( Nl != 0 ) { + String nl = unescape( Nl.data() ); + ConsItem *consItem = ConsItem::cons( + Nl.loc(), ConsItem::InputText, nl ); + ConsItemList *term = ConsItemList::cons( consItem ); + list = consListConcat( list, term ); + } + + return list; + } + + PatternItemList *walkLitpatElList( _repeat_litpat_el litpatElList, CONS_DQ_NL Nl, + LangVarRef *patternVarRef ) + { + PatternItemList *list = new PatternItemList; + while ( !litpatElList.end() ) { + PatternItemList *tail = walkLitpatEl( litpatElList.value(), patternVarRef ); + list = patListConcat( list, tail ); + litpatElList = litpatElList.next(); + } + + if ( Nl != 0 ) { + String nl = unescape( Nl.data() ); + PatternItem *patternItem = PatternItem::cons( PatternItem::InputTextForm, + Nl.loc(), nl ); + PatternItemList *term = PatternItemList::cons( patternItem ); + list = patListConcat( list, term ); + } + + return list; + } + + PatternItemList *walkPatternElList( _repeat_pattern_el patternElList, + LangVarRef *patternVarRef ) + { + PatternItemList *list = new PatternItemList; + while ( !patternElList.end() ) { + PatternItemList *tail = walkPatternEl( patternElList.value(), patternVarRef ); + list = patListConcat( list, tail ); + patternElList = patternElList.next(); + } + return list; + } + + PatternItemList *walkPattternTopEl( pattern_top_el patternTopEl, LangVarRef *patternVarRef ) + { + PatternItemList *list = 0; + switch ( patternTopEl.prodName() ) { + case pattern_top_el::_Dq: { + list = walkLitpatElList( patternTopEl.LitpatElList(), + patternTopEl.dq_lit_term().CONS_DQ_NL(), patternVarRef ); + break; + } + case pattern_top_el::_Sq: { + list = walkPatSqConsDataList( patternTopEl.SqConsDataList(), + patternTopEl.sq_lit_term().CONS_SQ_NL() ); + break; + } + case pattern_top_el::_Tilde: { + String patternData = patternTopEl.opt_tilde_data().text().c_str(); + patternData += '\n'; + PatternItem *patternItem = PatternItem::cons( PatternItem::InputTextForm, + patternTopEl.opt_tilde_data().loc(), patternData ); + list = PatternItemList::cons( patternItem ); + break; + } + case pattern_top_el::_SubList: { + list = walkPatternElList( patternTopEl.PatternElList(), patternVarRef ); + break; + }} + return list; + } + + PatternItemList *walkPatternList( pattern_list patternList, LangVarRef *patternVarRef ) + { + PatternItemList *list = 0; + switch ( patternList.prodName() ) { + case pattern_list::_List: { + PatternItemList *left = walkPatternList( patternList._pattern_list(), patternVarRef ); + PatternItemList *right = walkPattternTopEl( patternList.pattern_top_el(), patternVarRef ); + list = patListConcat( left, right ); + break; + } + case pattern_list::_Base: { + list = walkPattternTopEl( patternList.pattern_top_el(), patternVarRef ); + break; + }} + return list; + } + + PatternItemList *walkPattern( pattern Pattern, LangVarRef *patternVarRef ) + { + return walkPatternList( Pattern.pattern_list(), patternVarRef ); + } + + LangExpr *walkOptDefInit( opt_def_init optDefInit ) + { + LangExpr *expr = 0; + if ( optDefInit.prodName() == opt_def_init::_Init ) + expr = walkCodeExpr( optDefInit.code_expr() ); + return expr; + } + + LangStmt *walkExportDef( export_def exportDef ) + { + ObjectField *objField = walkVarDef( exportDef.var_def() ); + LangExpr *expr = walkOptDefInit( exportDef.opt_def_init() ); + + return exportStmt( objField, LangStmt::AssignType, expr ); + } + + LangStmt *walkGlobalDef( global_def GlobalDef ) + { + ObjectField *objField = walkVarDef( GlobalDef.var_def() ); + LangExpr *expr = walkOptDefInit( GlobalDef.opt_def_init() ); + + return globalDef( objField, expr, LangStmt::AssignType ); + } + + void walkAliasDef( alias_def aliasDef ) + { + String id = aliasDef.id().data(); + TypeRef *typeRef = walkTypeRef( aliasDef.type_ref() ); + alias( aliasDef.id().loc(), id, typeRef ); + } + + CodeBlock *walkOptTranslate( opt_translate optTranslate ) + { + CodeBlock *block = 0; + if ( optTranslate.prodName() == opt_translate::_Translate ) { + ObjectDef *localFrame = blockOpen(); + StmtList *stmtList = walkLangStmtList( optTranslate.lang_stmt_list() ); + block = CodeBlock::cons( stmtList, localFrame ); + block->context = curContext(); + blockClose(); + } + return block; + } + + PredDecl *walkPredToken( pred_token predToken ) + { + NamespaceQual *nspaceQual = walkRegionQual( predToken.region_qual() ); + PredDecl *predDecl = 0; + switch ( predToken.prodName() ) { + case pred_token::_Id: { + String id = predToken.id().data(); + predDecl = predTokenName( predToken.id().loc(), nspaceQual, id ); + break; + } + case pred_token::_Lit: { + String lit = predToken.backtick_lit().data(); + predDecl = predTokenLit( predToken.backtick_lit().loc(), lit, nspaceQual ); + break; + }} + return predDecl; + } + + PredDeclList *walkPredTokenList( pred_token_list predTokenList ) + { + PredDeclList *list = 0; + switch ( predTokenList.prodName() ) { + case pred_token_list::_List: { + list = walkPredTokenList( predTokenList._pred_token_list() ); + PredDecl *predDecl = walkPredToken( predTokenList.pred_token() ); + list->append( predDecl ); + break; + } + case pred_token_list::_Base: { + PredDecl *predDecl = walkPredToken( predTokenList.pred_token() ); + list = new PredDeclList; + list->append( predDecl ); + break; + }} + return list; + } + + PredType walkPredType( pred_type predType ) + { + PredType pt = PredLeft; + switch ( predType.prodName() ) { + case pred_type::_Left: + pt = PredLeft; + break; + case pred_type::_Right: + pt = PredRight; + break; + case pred_type::_NonAssoc: + pt = PredNonassoc; + break; + } + + return pt; + } + + void walkPrecedenceDef( precedence_def precedenceDef ) + { + PredType predType = walkPredType( precedenceDef.pred_type() ); + PredDeclList *predDeclList = walkPredTokenList( precedenceDef.pred_token_list() ); + precedenceStmt( predType, predDeclList ); + } + + StmtList *walkInclude( include Include ) + { + String lit = ""; + _repeat_sq_cons_data sqConsDataList = Include.SqConsDataList(); + while ( !sqConsDataList.end() ) { + colm_data *data = sqConsDataList.value().data(); + lit.append( data->data, data->length ); + sqConsDataList = sqConsDataList.next(); + } + + String file = unescape( lit ); + + const char *argv[2]; + argv[0] = file.data; + argv[1] = 0; + + colm_program *program = colm_new_program( &colm_object ); + colm_run_program( program, 1, argv ); + + /* Extract the parse tree. */ + start Start = ColmTree( program ); + str Error = ColmError( program ); + + if ( Start == 0 ) { + gblErrorCount += 1; + InputLoc loc = Error.loc(); + error(loc) << file.data << ": parse error: " << Error.text() << std::endl; + return 0; + } + + StmtList *stmtList = walkRootItemList( Start.RootItemList() ); + colm_delete_program( program ); + return stmtList; + } + + + NamespaceQual *walkRegionQual( region_qual regionQual ) + { + NamespaceQual *qual = 0; + switch ( regionQual.prodName() ) { + case region_qual::_Qual: { + qual = walkRegionQual( regionQual._region_qual() ); + qual->qualNames.append( String( regionQual.id().data() ) ); + break; + } + case region_qual::_Base: { + qual = NamespaceQual::cons( curNspace() ); + break; + }} + return qual; + } + + RepeatType walkOptRepeat( opt_repeat OptRepeat ) + { + RepeatType repeatType = RepeatNone; + switch ( OptRepeat.prodName() ) { + case opt_repeat::_Star: + repeatType = RepeatRepeat; + break; + case opt_repeat::_Plus: + repeatType = RepeatList; + break; + case opt_repeat::_Question: + repeatType = RepeatOpt; + break; + } + return repeatType; + } + + TypeRef *walkTypeRef( type_ref typeRef ) + { + TypeRef *tr = 0; + switch ( typeRef.prodName() ) { + case type_ref::_Id: { + NamespaceQual *nspaceQual = walkRegionQual( typeRef.region_qual() ); + String id = typeRef.id().data(); + RepeatType repeatType = walkOptRepeat( typeRef.opt_repeat() ); + tr = TypeRef::cons( typeRef.id().loc(), nspaceQual, id, repeatType ); + break; + } + case type_ref::_Ptr: { + NamespaceQual *nspaceQual = walkRegionQual( typeRef.region_qual() ); + String id = typeRef.id().data(); + RepeatType repeatType = walkOptRepeat( typeRef.opt_repeat() ); + TypeRef *inner = TypeRef::cons( typeRef.id().loc(), nspaceQual, id, repeatType ); + tr = TypeRef::cons( typeRef.id().loc(), TypeRef::Ptr, inner ); + break; + } + case type_ref::_Map: { + TypeRef *key = walkTypeRef( typeRef.MapKeyType() ); + TypeRef *value = walkTypeRef( typeRef.MapValueType() ); + tr = TypeRef::cons( typeRef.loc(), TypeRef::Map, 0, key, value ); + break; + } + case type_ref::_List: { + TypeRef *type = walkTypeRef( typeRef._type_ref() ); + tr = TypeRef::cons( typeRef.loc(), TypeRef::List, 0, type, 0 ); + break; + } + case type_ref::_Vector: { + TypeRef *type = walkTypeRef( typeRef._type_ref() ); + tr = TypeRef::cons( typeRef.loc(), TypeRef::Vector, 0, type, 0 ); + break; + } + case type_ref::_Parser: { + TypeRef *type = walkTypeRef( typeRef._type_ref() ); + tr = TypeRef::cons( typeRef.loc(), TypeRef::Parser, 0, type, 0 ); + break; + }} + return tr; + } + + StmtList *walkBlockOrSingle( block_or_single blockOrSingle ) + { + StmtList *stmtList = 0; + switch ( blockOrSingle.prodName() ) { + case block_or_single::_Single: { + stmtList = new StmtList; + LangStmt *stmt = walkStatement( blockOrSingle.statement() ); + stmtList->append( stmt ); + break; + } + case block_or_single::_Block: { + stmtList = walkLangStmtList( blockOrSingle.lang_stmt_list() ); + break; + }} + + return stmtList; + } + + void walkProdEl( const String &defName, ProdElList *list, prod_el El ) + { + ObjectField *captureField = 0; + if ( El.opt_prod_el_name().prodName() == opt_prod_el_name::_Name ) { + String fieldName = El.opt_prod_el_name().id().data(); + captureField = ObjectField::cons( El.opt_prod_el_name().id().loc(), 0, fieldName ); + } + else { + /* default the prod name. */ + if ( El.prodName() == prod_el::_Id ) { + String fieldName = El.id().data(); + opt_repeat::prod_name orpn = El.opt_repeat().prodName(); + if ( orpn == opt_repeat::_Star ) + fieldName = "_repeat_" + fieldName; + else if ( orpn == opt_repeat::_Plus ) + fieldName = "_list_" + fieldName; + else if ( orpn == opt_repeat::_Question ) + fieldName = "_opt_" + fieldName; + else if ( strcmp( fieldName, defName ) == 0 ) + fieldName = "_" + fieldName; + captureField = ObjectField::cons( El.id().loc(), 0, fieldName ); + } + } + + RepeatType repeatType = walkOptRepeat( El.opt_repeat() ); + NamespaceQual *nspaceQual = walkRegionQual( El.region_qual() ); + + switch ( El.prodName() ) { + case prod_el::_Id: { + String typeName = El.id().data(); + ProdEl *prodEl = prodElName( El.id().loc(), typeName, + nspaceQual, captureField, repeatType, false ); + appendProdEl( list, prodEl ); + break; + } + case prod_el::_Lit: { + String lit = El.backtick_lit().data(); + ProdEl *prodEl = prodElLiteral( El.backtick_lit().loc(), lit, + nspaceQual, captureField, repeatType, false ); + appendProdEl( list, prodEl ); + break; + }} + } + + void walkProdElList( const String &defName, ProdElList *list, prod_el_list ProdElList ) + { + if ( ProdElList.prodName() == prod_el_list::_List ) { + prod_el_list RightProdElList = ProdElList._prod_el_list(); + walkProdElList( defName, list, RightProdElList ); + walkProdEl( defName, list, ProdElList.prod_el() ); + } + } + + CodeBlock *walkOptReduce( opt_reduce OptReduce ) + { + CodeBlock *block = 0; + if ( OptReduce.prodName() == opt_reduce::_Reduce ) { + ObjectDef *localFrame = blockOpen(); + StmtList *stmtList = walkLangStmtList( OptReduce.lang_stmt_list() ); + + block = CodeBlock::cons( stmtList, localFrame ); + block->context = curContext(); + + blockClose(); + } + return block; + } + + void walkProdudction( const String &defName, LelDefList *lelDefList, prod Prod ) + { + ProdElList *list = new ProdElList; + + walkProdElList( defName, list, Prod.prod_el_list() ); + + String name; + if ( Prod.opt_prod_name().prodName() == opt_prod_name::_Name ) + name = Prod.opt_prod_name().id().data(); + + CodeBlock *codeBlock = walkOptReduce( Prod.opt_reduce() ); + bool commit = Prod.opt_commit().prodName() == opt_commit::_Commit; + + Production *prod = BaseParser::production( Prod.SQOPEN().loc(), + list, name, commit, codeBlock, 0 ); + prodAppend( lelDefList, prod ); + } + + void walkProdList( const String &name, LelDefList *lelDefList, prod_list ProdList ) + { + if ( ProdList.prodName() == prod_list::_List ) + walkProdList( name, lelDefList, ProdList._prod_list() ); + + walkProdudction( name, lelDefList, ProdList.prod() ); + } + + ReOrItem *walkRegOrChar( reg_or_char regOrChar ) + { + ReOrItem *orItem = 0; + switch ( regOrChar.prodName() ) { + case reg_or_char::_Char: { + String c = unescape( regOrChar.RE_CHAR().data() ); + orItem = ReOrItem::cons( regOrChar.RE_CHAR().loc(), c ); + break; + } + case reg_or_char::_Range: { + String low = unescape( regOrChar.Low().data() ); + String high = unescape( regOrChar.High().data() ); + orItem = ReOrItem::cons( regOrChar.Low().loc(), low[0], high[0] ); + break; + }} + return orItem; + } + + ReOrBlock *walkRegOrData( reg_or_data regOrData ) + { + ReOrBlock *block = 0; + switch ( regOrData.prodName() ) { + case reg_or_data::_Data: { + ReOrBlock *left = walkRegOrData( regOrData._reg_or_data() ); + ReOrItem *right = walkRegOrChar( regOrData.reg_or_char() ); + block = lexRegularExprData( left, right ); + break; + } + case reg_or_data::_Base: { + block = ReOrBlock::cons(); + break; + }} + return block; + } + + LexFactorNeg *walkLexFactorNeg( lex_factor_neg lexFactorNeg ) + { + LexFactorNeg *factorNeg = 0; + switch ( lexFactorNeg.prodName() ) { + case lex_factor_neg::_Caret: { + LexFactorNeg *recNeg = walkLexFactorNeg( lexFactorNeg._lex_factor_neg() ); + factorNeg = LexFactorNeg::cons( recNeg, LexFactorNeg::CharNegateType ); + break; + } + case lex_factor_neg::_Base: { + LexFactor *factor = walkLexFactor( lexFactorNeg.lex_factor() ); + factorNeg = LexFactorNeg::cons( factor ); + break; + }} + return factorNeg; + } + + LexFactorRep *walkLexFactorRep( lex_factor_rep lexFactorRep ) + { + LexFactorRep *factorRep = 0; + LexFactorRep *recRep = 0; + lex_factor_rep::prod_name pn = lexFactorRep.prodName(); + + if ( pn != lex_factor_rep::_Base ) + recRep = walkLexFactorRep( lexFactorRep._lex_factor_rep() ); + + switch ( pn ) { + case lex_factor_rep::_Star: { + factorRep = LexFactorRep::cons( lexFactorRep.LEX_STAR().loc(), + recRep, 0, 0, LexFactorRep::StarType ); + break; + } + case lex_factor_rep::_StarStar: { + factorRep = LexFactorRep::cons( lexFactorRep.LEX_STARSTAR().loc(), + recRep, 0, 0, LexFactorRep::StarStarType ); + break; + } + case lex_factor_rep::_Plus: { + factorRep = LexFactorRep::cons( lexFactorRep.LEX_PLUS().loc(), + recRep, 0, 0, LexFactorRep::PlusType ); + break; + } + case lex_factor_rep::_Question: { + factorRep = LexFactorRep::cons( lexFactorRep.LEX_QUESTION().loc(), + recRep, 0, 0, LexFactorRep::OptionalType ); + break; + } + case lex_factor_rep::_Exact: { + int low = atoi( lexFactorRep.lex_uint().data()->data ); + factorRep = LexFactorRep::cons( lexFactorRep.lex_uint().loc(), + recRep, low, 0, LexFactorRep::ExactType ); + break; + } + case lex_factor_rep::_Max: { + int high = atoi( lexFactorRep.lex_uint().data()->data ); + factorRep = LexFactorRep::cons( lexFactorRep.lex_uint().loc(), + recRep, 0, high, LexFactorRep::MaxType ); + break; + } + case lex_factor_rep::_Min: { + int low = atoi( lexFactorRep.lex_uint().data()->data ); + factorRep = LexFactorRep::cons( lexFactorRep.lex_uint().loc(), + recRep, low, 0, LexFactorRep::MinType ); + break; + } + case lex_factor_rep::_Range: { + int low = atoi( lexFactorRep.Low().data()->data ); + int high = atoi( lexFactorRep.High().data()->data ); + factorRep = LexFactorRep::cons( lexFactorRep.Low().loc(), + recRep, low, high, LexFactorRep::RangeType ); + break; + } + case lex_factor_rep::_Base: { + LexFactorNeg *factorNeg = walkLexFactorNeg( lexFactorRep.lex_factor_neg() ); + factorRep = LexFactorRep::cons( factorNeg ); + }} + + return factorRep; + } + + LexTerm *walkLexTerm( lex_term lexTerm ) + { + LexTerm *term = 0; + lex_term::prod_name pn = lexTerm.prodName(); + + LexTerm *leftTerm = 0; + if ( pn != lex_term::_Base ) + leftTerm = walkLexTerm( lexTerm._lex_term() ); + + LexFactorAug *factorAug = walkLexFactorAug( lexTerm.lex_factor_rep() ); + + switch ( pn ) { + case lex_term::_Dot: + term = LexTerm::cons( leftTerm, factorAug, LexTerm::ConcatType ); + break; + case lex_term::_ColonGt: + term = LexTerm::cons( leftTerm, factorAug, LexTerm::RightStartType ); + break; + case lex_term::_ColonGtGt: + term = LexTerm::cons( leftTerm, factorAug, LexTerm::RightFinishType ); + break; + case lex_term::_LtColon: + term = LexTerm::cons( leftTerm, factorAug, LexTerm::LeftType ); + break; + default: + term = LexTerm::cons( factorAug ); + break; + } + + return term; + } + + LexExpression *walkLexExpr( lex_expr lexExpr ) + { + LexExpression *expr = 0; + lex_expr::prod_name pn = lexExpr.prodName(); + + LexExpression *leftExpr = 0; + if ( pn != lex_expr::_Base ) + leftExpr = walkLexExpr( lexExpr._lex_expr() ); + + LexTerm *term = walkLexTerm( lexExpr.lex_term() ); + + switch ( pn ) { + case lex_expr::_Bar: + expr = LexExpression::cons( leftExpr, term, LexExpression::OrType ); + break; + case lex_expr::_Amp: + expr = LexExpression::cons( leftExpr, term, LexExpression::IntersectType ); + break; + case lex_expr::_Dash: + expr = LexExpression::cons( leftExpr, term, LexExpression::SubtractType ); + break; + case lex_expr::_DashDash: + expr = LexExpression::cons( leftExpr, term, LexExpression::StrongSubtractType ); + break; + case lex_expr::_Base: + expr = LexExpression::cons( term ); + } + return expr; + } + + + void walkRlDef( rl_def rlDef ) + { + String id = rlDef.id().data(); + + lex_expr LexExpr = rlDef.lex_expr(); + LexExpression *expr = walkLexExpr( LexExpr ); + LexJoin *join = LexJoin::cons( expr ); + + addRegularDef( rlDef.id().loc(), curNspace(), id, join ); + } + + void walkLexRegion( region_def regionDef ) + { + pushRegionSet( regionDef.loc() ); + walkRootItemList( regionDef.RootItemList() ); + popRegionSet(); + } + + void walkCflDef( cfl_def cflDef ) + { + String name = cflDef.id().data(); + ObjectDef *objectDef = walkVarDefList( cflDef.VarDefList() ); + objectDef->name = name; + + LelDefList *defList = new LelDefList; + walkProdList( name, defList, cflDef.prod_list() ); + + bool reduceFirst = cflDef.opt_reduce_first().REDUCEFIRST() != 0; + + NtDef *ntDef = NtDef::cons( name, curNspace(), + curContext(), reduceFirst ); + + BaseParser::cflDef( ntDef, objectDef, defList ); + } + + CallArgVect *walkCallArgList( call_arg_list callArgList ) + { + CallArgVect *callArgVect = new CallArgVect; + while ( callArgList.code_expr() != 0 ) { + code_expr codeExpr = callArgList.code_expr(); + LangExpr *expr = walkCodeExpr( codeExpr ); + callArgVect->append( new CallArg(expr) ); + callArgList = callArgList._call_arg_list(); + } + return callArgVect; + } + + LangStmt *walkPrintStmt( print_stmt &printStmt ) + { + CallArgVect *exprVect = walkCallArgList( printStmt.call_arg_list() ); + + LangStmt::Type type = LangStmt::PrintType; + switch ( printStmt.prodName() ) { + case print_stmt::_Tree: + type = LangStmt::PrintType; + break; + case print_stmt::_PrintStream: + type = LangStmt::PrintStreamType; + break; + case print_stmt::_Xml: + type = LangStmt::PrintXMLType; + break; + case print_stmt::_XmlAc: + type = LangStmt::PrintXMLACType; + break; + } + + return LangStmt::cons( printStmt.POPEN().loc(), type, exprVect ); + } + + QualItemVect *walkQual( qual &Qual ) + { + QualItemVect *qualItemVect = 0; + qual RecQual = Qual._qual(); + switch ( Qual.prodName() ) { + case qual::_Dot: + case qual::_Arrow: { + qualItemVect = walkQual( RecQual ); + String id = Qual.id().data(); + QualItem::Form form = Qual.DOT() != 0 ? QualItem::Dot : QualItem::Arrow; + qualItemVect->append( QualItem( form, Qual.id().loc(), id ) ); + break; + } + case qual::_Base: { + qualItemVect = new QualItemVect; + break; + }} + return qualItemVect; + } + + LangVarRef *walkVarRef( var_ref varRef ) + { + qual Qual = varRef.qual(); + QualItemVect *qualItemVect = walkQual( Qual ); + String id = varRef.id().data(); + LangVarRef *langVarRef = LangVarRef::cons( varRef.id().loc(), + curContext(), curScope, qualItemVect, id ); + return langVarRef; + } + + ObjectField *walkOptCapture( opt_capture optCapture ) + { + ObjectField *objField = 0; + if ( optCapture.prodName() == opt_capture::_Id ) { + String id = optCapture.id().data(); + objField = ObjectField::cons( optCapture.id().loc(), 0, id ); + } + return objField; + } + + /* + * Constructor + */ + + ConsItemList *walkLitConsEl( lit_cons_el litConsEl, TypeRef *consTypeRef ) + { + ConsItemList *list = 0; + switch ( litConsEl.prodName() ) { + case lit_cons_el::_ConsData: { + String consData = unescape( litConsEl.dq_cons_data().text().c_str() ); + ConsItem *consItem = ConsItem::cons( litConsEl.dq_cons_data().loc(), + ConsItem::InputText, consData ); + list = ConsItemList::cons( consItem ); + break; + } + case lit_cons_el::_SubList: { + list = walkConsElList( litConsEl.ConsElList(), consTypeRef ); + break; + }} + return list; + } + + ConsItemList *walkLitConsElList( _repeat_lit_cons_el litConsElList, + CONS_DQ_NL Nl, TypeRef *consTypeRef ) + { + ConsItemList *list = new ConsItemList; + while ( !litConsElList.end() ) { + ConsItemList *extension = walkLitConsEl( litConsElList.value(), consTypeRef ); + list = consListConcat( list, extension ); + litConsElList = litConsElList.next(); + } + + if ( Nl != 0 ) { + String consData = unescape( Nl.data() ); + ConsItem *consItem = ConsItem::cons( Nl.loc(), ConsItem::InputText, consData ); + ConsItemList *term = ConsItemList::cons( consItem ); + list = consListConcat( list, term ); + } + + return list; + } + + ConsItemList *walkConsEl( cons_el consEl, TypeRef *consTypeRef ) + { + ConsItemList *list = 0; + switch ( consEl.prodName() ) { + case cons_el::_Lit: { + NamespaceQual *nspaceQual = walkRegionQual( consEl.region_qual() ); + String lit = consEl.backtick_lit().data(); + list = consElLiteral( consEl.backtick_lit().loc(), consTypeRef, lit, nspaceQual ); + break; + } + case cons_el::_Tilde: { + String consData = consEl.opt_tilde_data().text().c_str(); + consData += '\n'; + ConsItem *consItem = ConsItem::cons( consEl.opt_tilde_data().loc(), + ConsItem::InputText, consData ); + list = ConsItemList::cons( consItem ); + break; + } + case cons_el::_Sq: { + list = walkConsSqConsDataList( consEl.SqConsDataList(), + consEl.sq_lit_term().CONS_SQ_NL() ); + break; + } + case cons_el::_CodeExpr: { + LangExpr *consExpr = walkCodeExpr( consEl.code_expr() ); + ConsItem *consItem = ConsItem::cons( consExpr->loc, + ConsItem::ExprType, consExpr ); + list = ConsItemList::cons( consItem ); + break; + } + case cons_el::_Dq: { + list = walkLitConsElList( consEl.LitConsElList(), + consEl.dq_lit_term().CONS_DQ_NL(), consTypeRef ); + break; + }} + return list; + } + + ConsItemList *walkConsElList( _repeat_cons_el consElList, TypeRef *consTypeRef ) + { + ConsItemList *list = new ConsItemList; + while ( !consElList.end() ) { + ConsItemList *extension = walkConsEl( consElList.value(), consTypeRef ); + list = consListConcat( list, extension ); + consElList = consElList.next(); + } + return list; + } + + ConsItemList *walkConsTopEl( cons_top_el consTopEl, TypeRef *consTypeRef ) + { + ConsItemList *list = 0; + switch ( consTopEl.prodName() ) { + case cons_top_el::_Dq: { + list = walkLitConsElList( consTopEl.LitConsElList(), + consTopEl.dq_lit_term().CONS_DQ_NL(), consTypeRef ); + break; + } + case cons_top_el::_Sq: { + list = walkConsSqConsDataList( consTopEl.SqConsDataList(), + consTopEl.sq_lit_term().CONS_SQ_NL() ); + break; + } + case cons_top_el::_Tilde: { + String consData = consTopEl.opt_tilde_data().text().c_str(); + consData += '\n'; + ConsItem *consItem = ConsItem::cons( consTopEl.opt_tilde_data().loc(), + ConsItem::InputText, consData ); + list = ConsItemList::cons( consItem ); + break; + } + case cons_top_el::_SubList: { + list = walkConsElList( consTopEl.ConsElList(), consTypeRef ); + break; + }} + return list; + } + + ConsItemList *walkConsList( cons_list consList, TypeRef *consTypeRef ) + { + ConsItemList *list = walkConsTopEl( consList.cons_top_el(), consTypeRef ); + + if ( consList._cons_list() != 0 ) { + ConsItemList *extension = walkConsList( consList._cons_list(), consTypeRef ); + consListConcat( list, extension ); + } + + return list; + } + + ConsItemList *walkConstructor( constructor Constructor, TypeRef *consTypeRef ) + { + ConsItemList *list = walkConsList( Constructor.cons_list(), consTypeRef ); + return list; + } + + /* + * String + */ + + ConsItemList *walkLitStringEl( lit_string_el litStringEl ) + { + ConsItemList *list = 0; + switch ( litStringEl.prodName() ) { + case lit_string_el::_ConsData: { + String consData = unescape( litStringEl.dq_cons_data().text().c_str() ); + ConsItem *stringItem = ConsItem::cons( litStringEl.dq_cons_data().loc(), + ConsItem::InputText, consData ); + list = ConsItemList::cons( stringItem ); + break; + } + case lit_string_el::_SubList: { + list = walkStringElList( litStringEl.StringElList() ); + break; + }} + return list; + } + + ConsItemList *walkLitStringElList( _repeat_lit_string_el litStringElList, CONS_DQ_NL Nl ) + { + ConsItemList *list = new ConsItemList; + while ( !litStringElList.end() ) { + ConsItemList *extension = walkLitStringEl( litStringElList.value() ); + list = consListConcat( list, extension ); + litStringElList = litStringElList.next(); + } + + if ( Nl != 0 ) { + String consData = unescape( Nl.data() ); + ConsItem *consItem = ConsItem::cons( Nl.loc(), + ConsItem::InputText, consData ); + ConsItemList *term = ConsItemList::cons( consItem ); + list = consListConcat( list, term ); + } + return list; + } + + ConsItemList *walkStringEl( string_el stringEl ) + { + ConsItemList *list = 0; + switch ( stringEl.prodName() ) { + case string_el::_Dq: { + list = walkLitStringElList( stringEl.LitStringElList(), + stringEl.dq_lit_term().CONS_DQ_NL() ); + break; + } + case string_el::_Sq: { + list = walkConsSqConsDataList( stringEl.SqConsDataList(), + stringEl.sq_lit_term().CONS_SQ_NL() ); + break; + } + case string_el::_Tilde: { + String consData = stringEl.opt_tilde_data().text().c_str(); + consData += '\n'; + ConsItem *consItem = ConsItem::cons( stringEl.opt_tilde_data().loc(), + ConsItem::InputText, consData ); + list = ConsItemList::cons( consItem ); + break; + } + case string_el::_CodeExpr: { + LangExpr *consExpr = walkCodeExpr( stringEl.code_expr() ); + ConsItem *consItem = ConsItem::cons( consExpr->loc, + ConsItem::ExprType, consExpr ); + list = ConsItemList::cons( consItem ); + break; + }} + return list; + } + + ConsItemList *walkStringElList( _repeat_string_el stringElList ) + { + ConsItemList *list = new ConsItemList; + while ( !stringElList.end() ) { + ConsItemList *extension = walkStringEl( stringElList.value() ); + list = consListConcat( list, extension ); + stringElList = stringElList.next(); + } + return list; + } + + ConsItemList *walkStringTopEl( string_top_el stringTopEl ) + { + ConsItemList *list = 0; + switch ( stringTopEl.prodName() ) { + case string_top_el::_Dq: { + list = walkLitStringElList( stringTopEl.LitStringElList(), + stringTopEl.dq_lit_term().CONS_DQ_NL() ); + break; + } + case string_el::_Sq: { + list = walkConsSqConsDataList( stringTopEl.SqConsDataList(), + stringTopEl.sq_lit_term().CONS_SQ_NL() ); + break; + } + case string_top_el::_Tilde: { + String consData = stringTopEl.opt_tilde_data().text().c_str(); + consData += '\n'; + ConsItem *consItem = ConsItem::cons( stringTopEl.opt_tilde_data().loc(), + ConsItem::InputText, consData ); + list = ConsItemList::cons( consItem ); + break; + } + case string_top_el::_SubList: { + list = walkStringElList( stringTopEl.StringElList() ); + break; + }} + return list; + } + + ConsItemList *walkStringList( string_list stringList ) + { + ConsItemList *list = walkStringTopEl( stringList.string_top_el() ); + + if ( stringList._string_list() != 0 ) { + ConsItemList *extension = walkStringList( stringList._string_list() ); + consListConcat( list, extension ); + } + + return list; + } + + ConsItemList *walkString( string String ) + { + ConsItemList *list = walkStringList( String.string_list() ); + return list; + } + + /* + * Accum + */ + + ConsItemList *walkLitAccumEl( lit_accum_el litAccumEl ) + { + ConsItemList *list = 0; + switch ( litAccumEl.prodName() ) { + case lit_accum_el::_ConsData: { + String consData = unescape( litAccumEl.dq_cons_data().text().c_str() ); + ConsItem *consItem = ConsItem::cons( litAccumEl.dq_cons_data().loc(), + ConsItem::InputText, consData ); + list = ConsItemList::cons( consItem ); + break; + } + case lit_accum_el::_SubList: { + list = walkAccumElList( litAccumEl.AccumElList() ); + break; + }} + return list; + } + + ConsItemList *walkLitAccumElList( _repeat_lit_accum_el litAccumElList, CONS_DQ_NL Nl ) + { + ConsItemList *list = new ConsItemList; + while ( !litAccumElList.end() ) { + ConsItemList *extension = walkLitAccumEl( litAccumElList.value() ); + list = consListConcat( list, extension ); + litAccumElList = litAccumElList.next(); + } + + if ( Nl != 0 ) { + String consData = unescape( Nl.data() ); + ConsItem *consItem = ConsItem::cons( Nl.loc(), ConsItem::InputText, consData ); + ConsItemList *term = ConsItemList::cons( consItem ); + list = consListConcat( list, term ); + } + + return list; + } + + ConsItemList *walkAccumEl( accum_el accumEl ) + { + ConsItemList *list = 0; + switch ( accumEl.prodName() ) { + case accum_el::_Dq: { + list = walkLitAccumElList( accumEl.LitAccumElList(), + accumEl.dq_lit_term().CONS_DQ_NL() ); + break; + } + case accum_el::_Sq: { + list = walkConsSqConsDataList( accumEl.SqConsDataList(), + accumEl.sq_lit_term().CONS_SQ_NL() ); + break; + } + case accum_el::_Tilde: { + String consData = accumEl.opt_tilde_data().text().c_str(); + consData += '\n'; + ConsItem *consItem = ConsItem::cons( accumEl.opt_tilde_data().loc(), + ConsItem::InputText, consData ); + list = ConsItemList::cons( consItem ); + break; + } + case accum_el::_CodeExpr: { + LangExpr *accumExpr = walkCodeExpr( accumEl.code_expr() ); + ConsItem *consItem = ConsItem::cons( accumExpr->loc, + ConsItem::ExprType, accumExpr ); + list = ConsItemList::cons( consItem ); + break; + }} + return list; + } + + ConsItemList *walkAccumElList( _repeat_accum_el accumElList ) + { + ConsItemList *list = new ConsItemList; + while ( !accumElList.end() ) { + ConsItemList *extension = walkAccumEl( accumElList.value() ); + list = consListConcat( list, extension ); + accumElList = accumElList.next(); + } + return list; + } + + ConsItemList *walkAccumTopEl( accum_top_el accumTopEl ) + { + ConsItemList *list = 0; + switch ( accumTopEl.prodName() ) { + case accum_top_el::_Dq: { + list = walkLitAccumElList( accumTopEl.LitAccumElList(), + accumTopEl.dq_lit_term().CONS_DQ_NL() ); + break; + } + case accum_top_el::_Sq: { + list = walkConsSqConsDataList( accumTopEl.SqConsDataList(), + accumTopEl.sq_lit_term().CONS_SQ_NL() ); + break; + } + case accum_top_el::_Tilde: { + String consData = accumTopEl.opt_tilde_data().text().c_str(); + consData += '\n'; + ConsItem *consItem = ConsItem::cons( accumTopEl.opt_tilde_data().loc(), + ConsItem::InputText, consData ); + list = ConsItemList::cons( consItem ); + break; + } + case accum_top_el::_SubList: { + list = walkAccumElList( accumTopEl.AccumElList() ); + break; + }} + return list; + } + + ConsItemList *walkAccumList( accum_list accumList ) + { + ConsItemList *list = walkAccumTopEl( accumList.accum_top_el() ); + + if ( accumList.prodName() == accum_list::_List ) { + ConsItemList *extension = walkAccumList( accumList._accum_list() ); + consListConcat( list, extension ); + } + + return list; + } + + ConsItemList *walkAccumulate( accumulate Accumulate ) + { + ConsItemList *list = walkAccumList( Accumulate.accum_list() ); + return list; + } + + void walkFieldInit( FieldInitVect *list, field_init fieldInit ) + { + LangExpr *expr = walkCodeExpr( fieldInit.code_expr() ); + FieldInit *init = FieldInit::cons( expr->loc, "_name", expr ); + list->append( init ); + } + + FieldInitVect *walkOptFieldInit( opt_field_init optFieldInit ) + { + FieldInitVect *list = 0; + if ( optFieldInit.prodName() == opt_field_init::_Init ) { + list = new FieldInitVect; + _repeat_field_init fieldInitList = optFieldInit.FieldInitList(); + while ( !fieldInitList.end() ) { + walkFieldInit( list, fieldInitList.value() ); + fieldInitList = fieldInitList.next(); + } + } + return list; + } + + LangExpr *walkCodeFactor( code_factor codeFactor ) + { + LangExpr *expr = 0; + switch ( codeFactor.prodName() ) { + case code_factor::_VarRef: { + LangVarRef *langVarRef = walkVarRef( codeFactor.var_ref() ); + LangTerm *term = LangTerm::cons( langVarRef->loc, + LangTerm::VarRefType, langVarRef ); + expr = LangExpr::cons( term ); + break; + } + case code_factor::_Call: { + LangVarRef *langVarRef = walkVarRef( codeFactor.var_ref() ); + CallArgVect *exprVect = walkCallArgList( codeFactor.call_arg_list() ); + LangTerm *term = LangTerm::cons( langVarRef->loc, langVarRef, exprVect ); + expr = LangExpr::cons( term ); + break; + } + case code_factor::_Number: { + String number = codeFactor.number().text().c_str(); + LangTerm *term = LangTerm::cons( codeFactor.number().loc(), + LangTerm::NumberType, number ); + expr = LangExpr::cons( term ); + break; + } + case code_factor::_Parse: { + /* The type we are parsing. */ + type_ref typeRefTree = codeFactor.type_ref(); + TypeRef *typeRef = walkTypeRef( typeRefTree ); + ObjectField *objField = walkOptCapture( codeFactor.opt_capture() ); + FieldInitVect *init = walkOptFieldInit( codeFactor.opt_field_init() ); + ConsItemList *list = walkAccumulate( codeFactor.accumulate() ); + + expr = parseCmd( codeFactor.PARSE().loc(), false, objField, + typeRef, init, list ); + break; + } + case code_factor::_ParseStop: { + /* The type we are parsing. */ + type_ref typeRefTree = codeFactor.type_ref(); + TypeRef *typeRef = walkTypeRef( typeRefTree ); + ObjectField *objField = walkOptCapture( codeFactor.opt_capture() ); + FieldInitVect *init = walkOptFieldInit( codeFactor.opt_field_init() ); + ConsItemList *list = walkAccumulate( codeFactor.accumulate() ); + + expr = parseCmd( codeFactor.PARSE_STOP().loc(), true, objField, + typeRef, init, list ); + break; + } + case code_factor::_Cons: { + /* The type we are parsing. */ + type_ref typeRefTree = codeFactor.type_ref(); + TypeRef *typeRef = walkTypeRef( typeRefTree ); + ObjectField *objField = walkOptCapture( codeFactor.opt_capture() ); + ConsItemList *list = walkConstructor( codeFactor.constructor(), typeRef ); + FieldInitVect *init = walkOptFieldInit( codeFactor.opt_field_init() ); + + expr = construct( codeFactor.CONS().loc(), objField, list, typeRef, init ); + break; + } + case code_factor::_Send: { + LangVarRef *varRef = walkVarRef( codeFactor.var_ref() ); + ConsItemList *list = walkAccumulate( codeFactor.accumulate() ); + bool eof = walkOptEos( codeFactor.opt_eos() ); + expr = send( codeFactor.SEND().loc(), varRef, list, eof ); + break; + } + case code_factor::_Nil: { + expr = LangExpr::cons( LangTerm::cons( codeFactor.NIL().loc(), + LangTerm::NilType ) ); + break; + } + case code_factor::_True: { + expr = LangExpr::cons( LangTerm::cons( codeFactor.TRUE().loc(), + LangTerm::TrueType ) ); + break; + } + case code_factor::_False: { + expr = LangExpr::cons( LangTerm::cons( codeFactor.FALSE().loc(), + LangTerm::FalseType ) ); + break; + } + case code_factor::_Paren: { + expr = walkCodeExpr( codeFactor.code_expr() ); + break; + } + case code_factor::_String: { + ConsItemList *list = walkString( codeFactor.string() ); + expr = LangExpr::cons( LangTerm::cons( codeFactor.string().loc(), list ) ); + break; + } + case code_factor::_Match: { + LangVarRef *varRef = walkVarRef( codeFactor.var_ref() ); + PatternItemList *list = walkPattern( codeFactor.pattern(), varRef ); + expr = match( codeFactor.loc(), varRef, list ); + break; + } + case code_factor::_In: { + TypeRef *typeRef = walkTypeRef( codeFactor.type_ref() ); + LangVarRef *varRef = walkVarRef( codeFactor.var_ref() ); + expr = LangExpr::cons( LangTerm::cons( typeRef->loc, + LangTerm::SearchType, typeRef, varRef ) ); + break; + } + case code_factor::_MakeTree: { + CallArgVect *exprList = walkCallArgList( codeFactor.call_arg_list() ); + expr = LangExpr::cons( LangTerm::cons( codeFactor.loc(), + LangTerm::MakeTreeType, exprList ) ); + break; + } + case code_factor::_MakeToken: { + CallArgVect *exprList = walkCallArgList( codeFactor.call_arg_list() ); + expr = LangExpr::cons( LangTerm::cons( codeFactor.loc(), + LangTerm::MakeTokenType, exprList ) ); + break; + } + case code_factor::_TypeId: { + TypeRef *typeRef = walkTypeRef( codeFactor.type_ref() ); + expr = LangExpr::cons( LangTerm::cons( codeFactor.loc(), + LangTerm::TypeIdType, typeRef ) ); + break; + } + case code_factor::_New: { + LangExpr *newExpr = walkCodeFactor( codeFactor._code_factor() ); + expr = LangExpr::cons( LangTerm::cons( codeFactor.loc(), + LangTerm::NewType, newExpr ) ); + break; + } + case code_factor::_Cast: { + TypeRef *typeRef = walkTypeRef( codeFactor.type_ref() ); + LangExpr *castExpr = walkCodeFactor( codeFactor._code_factor() ); + expr = LangExpr::cons( LangTerm::cons( codeFactor.loc(), + LangTerm::CastType, typeRef, castExpr ) ); + break; + }} + return expr; + } + + LangExpr *walkCodeAdditive( code_additive additive ) + { + LangExpr *expr = 0; + switch ( additive.prodName() ) { + case code_additive::_Plus: { + LangExpr *left = walkCodeAdditive( additive._code_additive() ); + LangExpr *right = walkCodeMultiplicitive( additive.code_multiplicitive() ); + expr = LangExpr::cons( additive.PLUS().loc(), left, '+', right ); + break; + } + case code_additive::_Minus: { + LangExpr *left = walkCodeAdditive( additive._code_additive() ); + LangExpr *right = walkCodeMultiplicitive( additive.code_multiplicitive() ); + expr = LangExpr::cons( additive.MINUS().loc(), left, '-', right ); + break; + } + case code_additive::_Base: { + expr = walkCodeMultiplicitive( additive.code_multiplicitive() ); + break; + }} + return expr; + } + + LangExpr *walkCodeUnary( code_unary unary ) + { + LangExpr *expr = 0, *factor = walkCodeFactor( unary.code_factor() ); + + switch ( unary.prodName() ) { + case code_unary::_Bang: { + expr = LangExpr::cons( unary.BANG().loc(), '!', factor ); + break; + } + case code_unary::_Dollar: { + expr = LangExpr::cons( unary.DOLLAR().loc(), '$', factor ); + break; + } + case code_unary::_Caret: { + expr = LangExpr::cons( unary.CARET().loc(), '^', factor ); + break; + } + case code_unary::_Percent: { + expr = LangExpr::cons( unary.PERCENT().loc(), '%', factor ); + break; + } + case code_unary::_Base: { + expr = factor; + }} + + return expr; + } + + LangExpr *walkCodeRelational( code_relational codeRelational ) + { + LangExpr *expr = 0, *left = 0; + + if ( codeRelational.prodName() != code_relational::_Base ) + left = walkCodeRelational( codeRelational._code_relational() ); + + LangExpr *additive = walkCodeAdditive( codeRelational.code_additive() ); + + switch ( codeRelational.prodName() ) { + case code_relational::_EqEq: { + expr = LangExpr::cons( codeRelational.loc(), left, OP_DoubleEql, additive ); + break; + } + case code_relational::_Neq: { + expr = LangExpr::cons( codeRelational.loc(), left, OP_NotEql, additive ); + break; + } + case code_relational::_Lt: { + expr = LangExpr::cons( codeRelational.loc(), left, '<', additive ); + break; + } + case code_relational::_Gt: { + expr = LangExpr::cons( codeRelational.loc(), left, '>', additive ); + break; + } + case code_relational::_LtEq: { + expr = LangExpr::cons( codeRelational.loc(), left, OP_LessEql, additive ); + break; + } + case code_relational::_GtEq: { + expr = LangExpr::cons( codeRelational.loc(), left, OP_GrtrEql, additive ); + break; + } + case code_relational::_Base: { + expr = additive; + break; + }} + return expr; + } + + LangStmt *walkExprStmt( expr_stmt exprStmt ) + { + LangExpr *expr = walkCodeExpr( exprStmt.code_expr() ); + LangStmt *stmt = LangStmt::cons( expr->loc, LangStmt::ExprType, expr ); + return stmt; + } + + ObjectField *walkVarDef( var_def varDef ) + { + String id = varDef.id().data(); + TypeRef *typeRef = walkTypeRef( varDef.type_ref() ); + return ObjectField::cons( varDef.id().loc(), typeRef, id ); + } + + IterCall *walkIterCall( iter_call Tree ) + { + IterCall *iterCall = 0; + switch ( Tree.prodName() ) { + case iter_call::_Call: { + LangVarRef *varRef = walkVarRef( Tree.var_ref() ); + CallArgVect *exprVect = walkCallArgList( Tree.call_arg_list() ); + LangTerm *langTerm = LangTerm::cons( varRef->loc, varRef, exprVect ); + iterCall = IterCall::cons( IterCall::IterCallForm, langTerm ); + break; + } + case iter_call::_Id: { + String tree = Tree.id().data(); + LangVarRef *varRef = LangVarRef::cons( Tree.id().loc(), + curContext(), curScope, tree ); + LangTerm *langTerm = LangTerm::cons( Tree.id().loc(), + LangTerm::VarRefType, varRef ); + LangExpr *langExpr = LangExpr::cons( langTerm ); + iterCall = IterCall::cons( IterCall::VarRefForm, langExpr ); + break; + } + case iter_call::_Expr: { + LangExpr *langExpr = walkCodeExpr( Tree.code_expr() ); + iterCall = IterCall::cons( IterCall::ExprForm, langExpr ); + break; + }} + + return iterCall; + } + + LangStmt *walkElsifClause( elsif_clause elsifClause ) + { + pushScope(); + LangExpr *expr = walkCodeExpr( elsifClause.code_expr() ); + StmtList *stmtList = walkBlockOrSingle( elsifClause.block_or_single() ); + LangStmt *stmt = LangStmt::cons( LangStmt::IfType, expr, stmtList, 0 ); + popScope(); + return stmt; + } + + LangStmt *walkOptionalElse( optional_else optionalElse ) + { + LangStmt *stmt = 0; + if ( optionalElse.prodName() == optional_else::_Else ) { + pushScope(); + StmtList *stmtList = walkBlockOrSingle( optionalElse.block_or_single() ); + stmt = LangStmt::cons( LangStmt::ElseType, stmtList ); + popScope(); + } + return stmt; + } + + LangStmt *walkElsifList( elsif_list elsifList ) + { + LangStmt *stmt = 0; + switch ( elsifList.prodName() ) { + case elsif_list::_Clause: + stmt = walkElsifClause( elsifList.elsif_clause() ); + stmt->elsePart = walkElsifList( elsifList._elsif_list() ); + break; + case elsif_list::_OptElse: + stmt = walkOptionalElse( elsifList.optional_else() ); + break; + } + return stmt; + } + + void walkContextVarDef( context_var_def ContextVarDef ) + { + ObjectField *objField = walkVarDef( ContextVarDef.var_def() ); + contextVarDef( objField->loc, objField ); + } + + TypeRef *walkReferenceTypeRef( reference_type_ref ReferenceTypeRef ) + { + TypeRef *typeRef = walkTypeRef( ReferenceTypeRef.type_ref() ); + return TypeRef::cons( ReferenceTypeRef.REF().loc(), TypeRef::Ref, typeRef ); + } + + ObjectField *walkParamVarDef( param_var_def paramVarDef ) + { + String id = paramVarDef.id().data(); + TypeRef *typeRef = 0; + + switch ( paramVarDef.prodName() ) { + case param_var_def::_Type: + typeRef = walkTypeRef( paramVarDef.type_ref() ); + break; + case param_var_def::_Ref: + typeRef = walkReferenceTypeRef( paramVarDef.reference_type_ref() ); + break; + } + + return addParam( paramVarDef.id().loc(), typeRef, id ); + } + + ParameterList *walkParamVarDefList( param_var_def_list paramVarDefList ) + { + ParameterList *paramList = new ParameterList; + while ( paramVarDefList.param_var_def() != 0 ) { + ObjectField *param = walkParamVarDef( paramVarDefList.param_var_def() ); + appendParam( paramList, param ); + paramVarDefList = paramVarDefList._param_var_def_list(); + } + return paramList; + } + + bool walkOptExport( opt_export OptExport ) + { + return OptExport.prodName() == opt_export::_Export; + } + + void walkFunctionDef( function_def FunctionDef ) + { + ObjectDef *localFrame = blockOpen(); + + bool exprt = walkOptExport( FunctionDef.opt_export() ); + TypeRef *typeRef = walkTypeRef( FunctionDef.type_ref() ); + String id = FunctionDef.id().data(); + ParameterList *paramList = walkParamVarDefList( FunctionDef.ParamVarDefList() ); + StmtList *stmtList = walkLangStmtList( FunctionDef.lang_stmt_list() ); + functionDef( stmtList, localFrame, paramList, typeRef, id, exprt ); + + blockClose(); + } + + void walkIterDef( iter_def IterDef ) + { + ObjectDef *localFrame = blockOpen(); + + String id = IterDef.id().data(); + ParameterList *paramList = walkParamVarDefList( IterDef.ParamVarDefList() ); + StmtList *stmtList = walkLangStmtList( IterDef.lang_stmt_list() ); + iterDef( stmtList, localFrame, paramList, id ); + + blockClose(); + } + + void walkContextItem( context_item contextItem ) + { + switch ( contextItem.prodName() ) { + case context_item::_Rl: + walkRlDef( contextItem.rl_def() ); + break; + case context_item::_ContextVar: + walkContextVarDef( contextItem.context_var_def() ); + break; + case context_item::_Token: + walkTokenDef( contextItem.token_def() ); + break; + case context_item::_IgnoreCollector: + walkIgnoreCollector( contextItem.ic_def() ); + break; + case context_item::_Ignore: + walkIgnoreDef( contextItem.ignore_def() ); + break; + case context_item::_Literal: + walkLiteralDef( contextItem.literal_def() ); + break; + case context_item::_Cfl: + walkCflDef( contextItem.cfl_def() ); + break; + case context_item::_Region: + walkLexRegion( contextItem.region_def() ); + break; + case context_item::_Context: + walkContextDef( contextItem.context_def() ); + break; + case context_item::_Function: + walkFunctionDef( contextItem.function_def() ); + break; + case context_item::_Iter: + walkIterDef( contextItem.iter_def() ); + break; + case context_item::_PreEof: + walkPreEof( contextItem.pre_eof_def() ); + break; + case context_item::_Export: + walkExportDef( contextItem.export_def() ); + break; + case context_item::_Precedence: + walkPrecedenceDef( contextItem.precedence_def() ); + break; + } + } + + void walkContextDef( context_def contextDef ) + { + String name = contextDef.id().data(); + contextHead( contextDef.id().loc(), name ); + + _repeat_context_item contextItemList = contextDef.ContextItemList(); + while ( !contextItemList.end() ) { + walkContextItem( contextItemList.value() ); + contextItemList = contextItemList.next(); + } + + contextStack.pop(); + namespaceStack.pop(); + } + + void walkNamespaceDef( namespace_def NamespaceDef ) + { + String name = NamespaceDef.id().data(); + createNamespace( NamespaceDef.id().loc(), name ); + walkNamespaceItemList( NamespaceDef.ItemList() ); + namespaceStack.pop(); + } + + void walkRootItem( root_item rootItem, StmtList *stmtList ) + { + switch ( rootItem.prodName() ) { + case root_item::_Rl: + walkRlDef( rootItem.rl_def() ); + break; + case root_item::_Token: + walkTokenDef( rootItem.token_def() ); + break; + case root_item::_IgnoreCollector: + walkIgnoreCollector( rootItem.ic_def() ); + break; + case root_item::_Ignore: + walkIgnoreDef( rootItem.ignore_def() ); + break; + case root_item::_Literal: + walkLiteralDef( rootItem.literal_def() ); + break; + case root_item::_Cfl: + walkCflDef( rootItem.cfl_def() ); + break; + case root_item::_Region: + walkLexRegion( rootItem.region_def() ); + break; + case root_item::_Statement: { + LangStmt *stmt = walkStatement( rootItem.statement() ); + if ( stmt != 0 ) + stmtList->append( stmt ); + break; + } + case root_item::_Context: + walkContextDef( rootItem.context_def() ); + break; + case root_item::_Namespace: + walkNamespaceDef( rootItem.namespace_def() ); + break; + case root_item::_Function: + walkFunctionDef( rootItem.function_def() ); + break; + case root_item::_Iter: + walkIterDef( rootItem.iter_def() ); + break; + case root_item::_PreEof: + walkPreEof( rootItem.pre_eof_def() ); + break; + case root_item::_Export: { + LangStmt *stmt = walkExportDef( rootItem.export_def() ); + if ( stmt != 0 ) + stmtList->append( stmt ); + break; + } + case root_item::_Alias: + walkAliasDef( rootItem.alias_def() ); + break; + case root_item::_Precedence: + walkPrecedenceDef( rootItem.precedence_def() ); + break; + case root_item::_Include: { + StmtList *includeList = walkInclude( rootItem.include() ); + stmtList->append( *includeList ); + break; + } + case root_item::_Global: { + LangStmt *stmt = walkGlobalDef( rootItem.global_def() ); + if ( stmt != 0 ) + stmtList->append( stmt ); + break; + }} + } + + void walkNamespaceItem( namespace_item item, StmtList *stmtList ) + { + switch ( item.prodName() ) { + case namespace_item::_Rl: + walkRlDef( item.rl_def() ); + break; + case namespace_item::_Token: + walkTokenDef( item.token_def() ); + break; + case root_item::_IgnoreCollector: + walkIgnoreCollector( item.ic_def() ); + break; + case namespace_item::_Ignore: + walkIgnoreDef( item.ignore_def() ); + break; + case namespace_item::_Literal: + walkLiteralDef( item.literal_def() ); + break; + case namespace_item::_Cfl: + walkCflDef( item.cfl_def() ); + break; + case namespace_item::_Region: + walkLexRegion( item.region_def() ); + break; + case namespace_item::_Context: + walkContextDef( item.context_def() ); + break; + case namespace_item::_Namespace: + walkNamespaceDef( item.namespace_def() ); + break; + case namespace_item::_Function: + walkFunctionDef( item.function_def() ); + break; + case namespace_item::_Iter: + walkIterDef( item.iter_def() ); + break; + case namespace_item::_PreEof: + walkPreEof( item.pre_eof_def() ); + break; + case namespace_item::_Alias: + walkAliasDef( item.alias_def() ); + break; + case namespace_item::_Precedence: + walkPrecedenceDef( item.precedence_def() ); + break; + case namespace_item::_Include: { + StmtList *includeList = walkInclude( item.include() ); + stmtList->append( *includeList ); + break; + }} + } + + bool walkNoIgnoreLeft( no_ignore_left OptNoIngore ) + { + return OptNoIngore.prodName() == no_ignore_left::_Ni; + } + + bool walkNoIgnoreRight( no_ignore_right OptNoIngore ) + { + return OptNoIngore.prodName() == no_ignore_right::_Ni; + } + + bool walkOptEos( opt_eos OptEos ) + { + opt_eos::prod_name pn = OptEos.prodName(); + return pn == opt_eos::_Dot || pn == opt_eos::_Eos; + } + + void walkLiteralItem( literal_item literalItem ) + { + bool niLeft = walkNoIgnoreLeft( literalItem.no_ignore_left() ); + bool niRight = walkNoIgnoreRight( literalItem.no_ignore_right() ); + + String lit = literalItem.backtick_lit().data(); + literalDef( literalItem.backtick_lit().loc(), lit, niLeft, niRight ); + } + + void walkLiteralList( literal_list literalList ) + { + if ( literalList.prodName() == literal_list::_Item ) + walkLiteralList( literalList._literal_list() ); + walkLiteralItem( literalList.literal_item() ); + } + + void walkLiteralDef( literal_def literalDef ) + { + walkLiteralList( literalDef.literal_list() ); + } + + StmtList *walkNamespaceItemList( _repeat_namespace_item itemList ) + { + StmtList *stmtList = new StmtList; + + /* Walk the list of items. */ + while ( !itemList.end() ) { + walkNamespaceItem( itemList.value(), stmtList ); + itemList = itemList.next(); + } + return stmtList; + } + + + StmtList *walkRootItemList( _repeat_root_item rootItemList ) + { + StmtList *stmtList = new StmtList; + + /* Walk the list of items. */ + while ( !rootItemList.end() ) { + walkRootItem( rootItemList.value(), stmtList ); + rootItemList = rootItemList.next(); + } + return stmtList; + } + + virtual void go( long activeRealm ); +}; + +void LoadColm::go( long activeRealm ) +{ + LoadColm::init(); + + const char *argv[2]; + argv[0] = inputFileName; + argv[1] = 0; + + colm_program *program = colm_new_program( &colm_object ); + colm_set_debug( program, activeRealm ); + colm_run_program( program, 1, argv ); + + /* Extract the parse tree. */ + start Start = ColmTree( program ); + str Error = ColmError( program ); + + if ( Start == 0 ) { + gblErrorCount += 1; + InputLoc loc = Error.loc(); + error(loc) << inputFileName << ": parse error: " << Error.text() << std::endl; + return; + } + + StmtList *stmtList = walkRootItemList( Start.RootItemList() ); + colm_delete_program( program ); + + pd->rootCodeBlock = CodeBlock::cons( stmtList, 0 ); +} + +BaseParser *consLoadColm( Compiler *pd, const char *inputFileName ) +{ + return new LoadColm( pd, inputFileName ); +} |