summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2013-04-16 01:40:44 +0000
committerAdrian Thurston <thurston@complang.org>2013-04-16 01:40:44 +0000
commit57792f74d182239d0b58144aab7114d85c5fa6f7 (patch)
treea753a9cae2a8f45382a299ff5f185bd94a03c8ca
parent6cf5147ad5e296e85281a8e333a96802246adb3c (diff)
downloadcolm-57792f74d182239d0b58144aab7114d85c5fa6f7.tar.gz
added a function export syntax and call adapter
-rw-r--r--colm/bytecode.c8
-rw-r--r--colm/colm.h1
-rw-r--r--colm/colm.lm7
-rw-r--r--colm/exports.cc43
-rw-r--r--colm/loadcolm.cc8
-rw-r--r--colm/parser.cc6
-rw-r--r--colm/parser.h2
-rw-r--r--colm/parsetree.h4
-rw-r--r--colm/program.c48
-rw-r--r--colm/program.h2
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;