From 57792f74d182239d0b58144aab7114d85c5fa6f7 Mon Sep 17 00:00:00 2001 From: Adrian Thurston Date: Tue, 16 Apr 2013 01:40:44 +0000 Subject: added a function export syntax and call adapter --- colm/bytecode.c | 8 ++++++++ colm/colm.h | 1 + colm/colm.lm | 7 ++++++- colm/exports.cc | 43 ++++++++++++++++++++++++++++++++++++++++++- colm/loadcolm.cc | 8 +++++++- colm/parser.cc | 6 +++--- colm/parser.h | 2 +- colm/parsetree.h | 4 +++- colm/program.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ colm/program.h | 2 +- 10 files changed, 120 insertions(+), 9 deletions(-) diff --git a/colm/bytecode.c b/colm/bytecode.c index 4cfd573e..b06bdd24 100644 --- a/colm/bytecode.c +++ b/colm/bytecode.c @@ -723,6 +723,7 @@ void mainExecution( Program *prg, Execution *exec, Code *code ) vm_pop_ignore(); vm_pop_ignore(); + treeDownref( prg, sp, prg->returnVal ); prg->returnVal = vm_pop(); vm_pop_ignore(); @@ -3483,6 +3484,13 @@ again: Tree *retVal = vm_pop(); vm_popn( fi->argSize ); vm_push( retVal ); + + /* This if for direct calls of functions. */ + if ( instr == 0 ){ + //assert( sp == root ); + return sp; + } + break; } case IN_TO_UPPER: { diff --git a/colm/colm.h b/colm/colm.h index a4d6e9fa..f5183be2 100644 --- a/colm/colm.h +++ b/colm/colm.h @@ -14,6 +14,7 @@ struct ColmLocation; struct ColmProgram *colmNewProgram( struct ColmRuntimeData *rtd, long debugRealm ); void colmRunProgram( struct ColmProgram *prg, int argc, const char **argv ); +struct ColmTree *colmRunFunc( struct ColmProgram *prg, int frameId, const char **params, int paramCount ); int colmDeleteProgram( struct ColmProgram *prg ); struct ColmPrintArgs diff --git a/colm/colm.lm b/colm/colm.lm index 63f8e378..f8668337 100644 --- a/colm/colm.lm +++ b/colm/colm.lm @@ -258,8 +258,13 @@ def param_var_def [Id: id COLON TypeRef: type_ref] | [Id: id COLON RefTypeRef: reference_type_ref] +def opt_export + [Export: EXPORT] +| [] + def function_def - [TypeRef: type_ref Id: id POPEN ParamVarDefList: param_var_def* PCLOSE + [OptExport: opt_export TypeRef: type_ref Id: id + POPEN ParamVarDefList: param_var_def* PCLOSE COPEN LangStmtList: lang_stmt_list CCLOSE] def context_var_def diff --git a/colm/exports.cc b/colm/exports.cc index edcc7ca4..73ac48fe 100644 --- a/colm/exports.cc +++ b/colm/exports.cc @@ -161,6 +161,22 @@ void Compiler::generateExports() } } + out << "\n"; + + for ( FunctionList::Iter func = functionList; func.lte(); func++ ) { + if ( func->exprt ) { + char *refName = func->typeRef->uniqueType->langEl->refName; + int paramCount = func->paramList->length(); + out << + refName << " " << func->name << "( ColmProgram *prg"; + + for ( int p = 0; p < paramCount; p++ ) + out << ", const char *p" << p; + + out << " );\n"; + } + } + out << "#endif\n"; } @@ -245,6 +261,31 @@ void Compiler::generateExportsImpl() } } } -} + out << "\n"; + + for ( FunctionList::Iter func = functionList; func.lte(); func++ ) { + if ( func->exprt ) { + char *refName = func->typeRef->uniqueType->langEl->refName; + int paramCount = func->paramList->length(); + out << + refName << " " << func->name << "( ColmProgram *prg"; + + for ( int p = 0; p < paramCount; p++ ) + out << ", const char *p" << p; + + out << " )\n" + "{\n" + " int funcId = " << func->funcId << ";\n" + " const char *params[" << paramCount << "];\n"; + for ( int p = 0; p < paramCount; p++ ) + out << " params[" << p << "] = p" << p << ";\n"; + + out << + " return " << refName << + "( prg, colmRunFunc( prg, funcId, params, " << paramCount << " ));\n" + "}\n"; + } + } +} diff --git a/colm/loadcolm.cc b/colm/loadcolm.cc index 995153db..8c31813c 100644 --- a/colm/loadcolm.cc +++ b/colm/loadcolm.cc @@ -1684,15 +1684,21 @@ struct LoadColm return paramList; } + bool walkOptExport( opt_export OptExport ) + { + return OptExport.Export() != 0; + } + void walkFunctionDef( function_def FunctionDef ) { ObjectDef *localFrame = blockOpen(); + bool exprt = walkOptExport( FunctionDef.OptExport() ); TypeRef *typeRef = walkTypeRef( FunctionDef.TypeRef() ); String id = FunctionDef.Id().text().c_str(); ParameterList *paramList = walkParamVarDefList( FunctionDef.ParamVarDefList() ); StmtList *stmtList = walkLangStmtList( FunctionDef.LangStmtList() ); - functionDef( stmtList, localFrame, paramList, typeRef, id ); + functionDef( stmtList, localFrame, paramList, typeRef, id, exprt ); blockClose(); } diff --git a/colm/parser.cc b/colm/parser.cc index 3b60cb77..b2dde7d8 100644 --- a/colm/parser.cc +++ b/colm/parser.cc @@ -340,11 +340,11 @@ void BaseParser::blockClose() } void BaseParser::functionDef( StmtList *stmtList, ObjectDef *localFrame, - ParameterList *paramList, TypeRef *typeRef, const String &name ) + ParameterList *paramList, TypeRef *typeRef, const String &name, bool exprt ) { CodeBlock *codeBlock = CodeBlock::cons( stmtList, localFrame ); Function *newFunction = Function::cons( typeRef, name, - paramList, codeBlock, pd->nextFuncId++, false ); + paramList, codeBlock, pd->nextFuncId++, false, exprt ); pd->functionList.append( newFunction ); newFunction->inContext = contextStack.top(); } @@ -354,7 +354,7 @@ void BaseParser::iterDef( StmtList *stmtList, ObjectDef *localFrame, { CodeBlock *codeBlock = CodeBlock::cons( stmtList, localFrame ); Function *newFunction = Function::cons( 0, name, - paramList, codeBlock, pd->nextFuncId++, true ); + paramList, codeBlock, pd->nextFuncId++, true, false ); pd->functionList.append( newFunction ); } diff --git a/colm/parser.h b/colm/parser.h index 55af2c4f..27daffcf 100644 --- a/colm/parser.h +++ b/colm/parser.h @@ -73,7 +73,7 @@ struct BaseParser ObjectDef *blockOpen(); void blockClose(); void functionDef( StmtList *stmtList, ObjectDef *localFrame, - ParameterList *paramList, TypeRef *typeRef, const String &name ); + ParameterList *paramList, TypeRef *typeRef, const String &name, bool exprt ); void iterDef( StmtList *stmtList, ObjectDef *localFrame, ParameterList *paramList, const String &name ); LangStmt *globalDef( ObjectField *objField, LangExpr *expr, LangStmt::Type assignType ); diff --git a/colm/parsetree.h b/colm/parsetree.h index 24bcdc74..e2b24947 100644 --- a/colm/parsetree.h +++ b/colm/parsetree.h @@ -2923,7 +2923,7 @@ struct Function static Function *cons( TypeRef *typeRef, const String &name, ParameterList *paramList, CodeBlock *codeBlock, - int funcId, bool isUserIter ) + int funcId, bool isUserIter, bool exprt ) { Function *f = new Function; @@ -2933,6 +2933,7 @@ struct Function f->codeBlock = codeBlock; f->funcId = funcId; f->isUserIter = isUserIter; + f->exprt = exprt; return f; } @@ -2948,6 +2949,7 @@ struct Function long paramListSize; UniqueType **paramUTs; Context *inContext; + bool exprt; Function *prev, *next; }; diff --git a/colm/program.c b/colm/program.c index d781a57e..6548cba4 100644 --- a/colm/program.c +++ b/colm/program.c @@ -246,6 +246,54 @@ void colmRunProgram( Program *prg, int argc, const char **argv ) prg->argv = 0; } +Tree *colmRunFunc( struct ColmProgram *prg, int frameId, const char **params, int paramCount ) +{ + /* Make the arguments available to the program. */ + prg->argc = 0; + prg->argv = 0; + + Execution execution; + memset( &execution, 0, sizeof(execution) ); + + Tree **sp = prg->stackRoot; + + FrameInfo *fi = &prg->rtd->frameInfo[frameId]; + Code *code = fi->codeWC; + long stretch = fi->argSize + 4 + fi->frameSize; + vm_contiguous( stretch ); + + int p; + for ( p = 0; p < paramCount; p++ ) { + if ( params[p] == 0 ) { + vm_push( 0 ); + } + else { + Head *head = stringAllocPointer( prg, params[p], strlen(params[p]) ); + Tree *tree = constructString( prg, head ); + treeUpref( tree ); + vm_push( tree ); + } + } + + /* Set up the stack as if we have called. We allow a return value. */ + vm_push( 0 ); + vm_push( 0 ); + vm_push( 0 ); + vm_push( 0 ); + + execution.framePtr = vm_ptop(); + execution.frameId = frameId; + + /* Execution loop. */ + sp = executeCode( prg, &execution, sp, code ); + + treeDownref( prg, sp, prg->returnVal ); + prg->returnVal = vm_pop(); + + assert( sp == prg->stackRoot ); + + return prg->returnVal; +}; int colmDeleteProgram( Program *prg ) { diff --git a/colm/program.h b/colm/program.h index d1b57f64..60cede1e 100644 --- a/colm/program.h +++ b/colm/program.h @@ -141,7 +141,7 @@ typedef struct ColmProgram StackBlock *stackBlock; Tree **stackRoot; - /* Returned from the main line. Should have exports instead. */ + /* Returned value for main program and any exported functions. */ Tree *returnVal; } Program; -- cgit v1.2.1