basic support for binding to libraries

This commit is contained in:
Justin Meza 2013-02-24 02:40:58 -05:00
parent 2014412d5b
commit 38e67f8287
6 changed files with 148 additions and 39 deletions

125
binding.c
View File

@ -2,42 +2,119 @@
struct returnobject;
struct scopeobject;
struct returnobject *fopenWrapper(struct scopeobject *scope)
{
fprintf(stderr, "HERE\n");
IdentifierNode *id1 = createIdentifierNode(IT_DIRECT, (void *)copyString("filename"), NULL, NULL, 0);
ValueObject *val1 = getScopeValueLocal(scope, scope, id1);
IdentifierNode *id2 = createIdentifierNode(IT_DIRECT, (void *)copyString("mode"), NULL, NULL, 0);
ValueObject *val2 = getScopeValueLocal(scope, scope, id2);
char *filename = getString(val1);
char *mode = getString(val2);
FILE *f = fopen(filename, mode);
ValueObject *ret = createBlobValueObject(f);
return createReturnObject(RT_RETURN, ret);
}
struct returnobject *freadWrapper(struct scopeobject *scope)
{
IdentifierNode *id1 = createIdentifierNode(IT_DIRECT, (void *)copyString("file"), NULL, NULL, 0);
ValueObject *val1 = getScopeValueLocal(scope, scope, id1);
IdentifierNode *id2 = createIdentifierNode(IT_DIRECT, (void *)copyString("length"), NULL, NULL, 0);
ValueObject *val2 = getScopeValueLocal(scope, scope, id2);
FILE *file = (FILE *)getBlob(val1);
int length = getInteger(val2);
char *buf = malloc((sizeof(char) * length) + 1);
fread(buf, 1, length, file);
buf[length] = '\0';
ValueObject *ret = createStringValueObject(buf);
return createReturnObject(RT_RETURN, ret);
}
struct returnobject *fcloseWrapper(struct scopeobject *scope)
{
IdentifierNode *id1 = createIdentifierNode(IT_DIRECT, (void *)copyString("file"), NULL, NULL, 0);
ValueObject *val1 = getScopeValueLocal(scope, scope, id1);
FILE *file = (FILE *)getBlob(val1);
fclose(file);
return createReturnObject(RT_DEFAULT, NULL);
}
void loadBinding(ScopeObject *scope)
{
/* TODO: add error checking and handling */
/* TODO: add error checking and handling */
/* stdio */
/* stdio */
ScopeObject *stdio = createScopeObject(scope);
IdentifierNode* name_stdio = createIdentifierNode(IT_DIRECT, (void *)copyString("STDIO"), NULL, NULL, 0);
createScopeValue(scope, scope, name_stdio);
ValueObject *val_stdio = createArrayValueObject(stdio);
updateScopeValue(scope, scope, name_stdio, val_stdio);
Binding *fopen = malloc(sizeof(Binding));
/* fopen */
{
IdentifierNode* name = createIdentifierNode(IT_DIRECT, (void *)copyString("FOPENIN"), NULL, NULL, 0);
IdentifierNodeList *args = createIdentifierNodeList();
IdentifierNode *filename = createIdentifierNode(IT_DIRECT, (void *)copyString("filename"), NULL, NULL, 0);
IdentifierNode *mode = createIdentifierNode(IT_DIRECT, (void *)copyString("mode"), NULL, NULL, 0);
addIdentifierNode(args, filename);
addIdentifierNode(args, mode);
StmtNodeList *stmts = createStmtNodeList();
BindingStmtNode *binding = createBindingStmtNode(&fopenWrapper);
StmtNode *wrapper = createStmtNode(ST_BINDING, binding);
addStmtNode(stmts, wrapper);
BlockNode *body = createBlockNode(stmts);
/* TODO: should this first parameter be NULL? */
FuncDefStmtNode *interface = createFuncDefStmtNode(NULL, name, args, body);
ValueObject *val = createFunctionValueObject(interface);
createScopeValue(stdio, stdio, name);
updateScopeValue(stdio, stdio, name, val);
}
fopen->library = createIdentifierNode(IT_DIRECT, (void *)copyString("STDIO"), NULL, NULL, 0);
/* fread */
{
IdentifierNode* name = createIdentifierNode(IT_DIRECT, (void *)copyString("FREADIN"), NULL, NULL, 0);
IdentifierNodeList *args = createIdentifierNodeList();
IdentifierNode *filename = createIdentifierNode(IT_DIRECT, (void *)copyString("file"), NULL, NULL, 0);
IdentifierNode *mode = createIdentifierNode(IT_DIRECT, (void *)copyString("length"), NULL, NULL, 0);
addIdentifierNode(args, filename);
addIdentifierNode(args, mode);
StmtNodeList *stmts = createStmtNodeList();
BindingStmtNode *binding = createBindingStmtNode(&freadWrapper);
StmtNode *wrapper = createStmtNode(ST_BINDING, binding);
addStmtNode(stmts, wrapper);
BlockNode *body = createBlockNode(stmts);
/* TODO: should this first parameter be NULL? */
FuncDefStmtNode *interface = createFuncDefStmtNode(NULL, name, args, body);
ValueObject *val = createFunctionValueObject(interface);
createScopeValue(stdio, stdio, name);
updateScopeValue(stdio, stdio, name, val);
}
IdentifierNode* name = createIdentifierNode(IT_DIRECT, (void *)copyString("FOPENIN"), NULL, NULL, 0);
IdentifierNodeList *args = createIdentifierNodeList();
IdentifierNode *filename = createIdentifierNode(IT_DIRECT, (void *)copyString("filename"), NULL, NULL, 0);
IdentifierNode *mode = createIdentifierNode(IT_DIRECT, (void *)copyString("mode"), NULL, NULL, 0);
addIdentifierNode(args, filename);
addIdentifierNode(args, mode);
StmtNodeList *stmts = createStmtNodeList();
BindingStmtNode *binding = createBindingStmtNode(&fopenWrapper);
StmtNode *wrapper = createStmtNode(ST_BINDING, binding);
addStmtNode(stmts, wrapper);
BlockNode *body = createBlockNode(stmts);
/* TODO: should this first parameter be NULL? */
fopen->interface = createFuncDefStmtNode(NULL, name, args, body);
ValueObject *val = createFunctionValueObject(fopen->interface);
/* fclose */
{
IdentifierNode* name = createIdentifierNode(IT_DIRECT, (void *)copyString("FCLOSIN"), NULL, NULL, 0);
IdentifierNodeList *args = createIdentifierNodeList();
IdentifierNode *filename = createIdentifierNode(IT_DIRECT, (void *)copyString("file"), NULL, NULL, 0);
addIdentifierNode(args, filename);
StmtNodeList *stmts = createStmtNodeList();
BindingStmtNode *binding = createBindingStmtNode(&fcloseWrapper);
StmtNode *wrapper = createStmtNode(ST_BINDING, binding);
addStmtNode(stmts, wrapper);
BlockNode *body = createBlockNode(stmts);
FuncDefStmtNode *interface = createFuncDefStmtNode(NULL, name, args, body);
ValueObject *val = createFunctionValueObject(interface);
createScopeValue(stdio, stdio, name);
updateScopeValue(stdio, stdio, name, val);
}
createScopeValue(scope, scope, name);
updateScopeValue(scope, scope, name, val);
return;
return;
loadBindingAbort: /* Exception handling */
return;
return;
}

View File

@ -19,8 +19,8 @@
* Stores a binding to an external library call to export.
*/
typedef struct {
IdentifierNode *library; /**< The library this binding belongs to. */
FuncDefStmtNode *interface; /**< The interface that exports the binding. */
IdentifierNode *library; /**< The library this binding belongs to. */
FuncDefStmtNode *interface; /**< The interface that exports the binding. */
} Binding;
void loadBinding(ScopeObject *); /* TODO: make this take an IdentifierNode library to load */
@ -37,12 +37,12 @@ void loadBinding(ScopeObject *); /* TODO: make this take an IdentifierNode libra
* the scope.
* - Binding creation/deletion helper functions.
IdentifierNode *scope = ??? what goes here again?;
IdentifierNode *name = createIdentifierNode("FileOpen");
IdentifierNodeList *args = ... add these ...
BlockNode *block = ... block with appropriate BindingStmtNode ...
FuncDefStmtNode *def = createFuncDefStmtNode();
Binding *binding = createBinding("STDIO", def);
IdentifierNode *scope = ??? what goes here again?;
IdentifierNode *name = createIdentifierNode("FileOpen");
IdentifierNodeList *args = ... add these ...
BlockNode *block = ... block with appropriate BindingStmtNode ...
FuncDefStmtNode *def = createFuncDefStmtNode();
Binding *binding = createBinding("STDIO", def);
*/

View File

@ -306,6 +306,30 @@ ValueObject *createArrayValueObject(ScopeObject *parent)
return p;
}
/**
* Creates a blob-type value.
*
* \param [in] data The binary blob data to store.
*
* \note \a data is stored as-is; no copy of it is made.
*
* \return A string-type value equalling \a data.
*
* \retval NULL Memory allocation failed.
*/
ValueObject *createBlobValueObject(void *data)
{
ValueObject *p = malloc(sizeof(ValueObject));
if (!p) {
perror("malloc");
return NULL;
}
p->type = VT_BLOB;
p->data.b = data;
p->semaphore = 1;
return p;
}
/**
* Copies a value.
*
@ -3656,7 +3680,7 @@ ReturnObject *interpretBindingStmtNode(StmtNode *node,
ScopeObject *scope)
{
BindingStmtNode *stmt = (BindingStmtNode *)node->stmt;
return (stmt->binding)(scope);
return (stmt->binding)(scope);
}
/*
@ -3776,7 +3800,7 @@ int interpretMainNode(MainNode *main)
if (!main) return 1;
ScopeObject *libs = createScopeObject(NULL);
if (!libs) return 1;
loadBinding(libs);
loadBinding(libs);
ret = interpretBlockNode(main->block, libs);
if (!ret) return 1;
deleteReturnObject(ret);

View File

@ -46,6 +46,11 @@
*/
#define getArray(value) (value->data.a)
/**
* Retrieves a value's blob data.
*/
#define getBlob(value) (value->data.b)
/**
* Represents a value type.
*/
@ -56,7 +61,8 @@ typedef enum {
VT_STRING, /**< A string value. */
VT_NIL, /**< Represents no value. */
VT_FUNC, /**< A function. */
VT_ARRAY /**< An array. */
VT_ARRAY, /**< An array. */
VT_BLOB /**< A binary blob of data. */
} ValueType;
/**
@ -68,6 +74,7 @@ typedef union {
char *s; /**< String data. */
FuncDefStmtNode *fn; /**< Function data. */
struct scopeobject *a; /**< Array data. */
void *b; /**< Binary blob data. */
} ValueData;
/**
@ -144,6 +151,7 @@ ValueObject *createFloatValueObject(float);
ValueObject *createStringValueObject(char *);
ValueObject *createFunctionValueObject(FuncDefStmtNode *);
ValueObject *createArrayValueObject(ScopeObject *);
ValueObject *createBlobValueObject(void *);
ValueObject *copyValueObject(ValueObject *);
void deleteValueObject(ValueObject *);
/**@}*/

2
main.c
View File

@ -151,7 +151,7 @@ int main(int argc, char **argv)
FILE *file = NULL;
int ch;
char *revision = "v0.10.3";
char *revision = "v0.11.3";
program_name = argv[0];
while ((ch = getopt_long(argc, argv, shortopt, longopt, NULL)) != -1) {

View File

@ -368,10 +368,10 @@ typedef struct {
/**
* Stores a binding to a native function.
*/
struct ReturnObject;
struct ScopeObject;
struct returnobject;
struct scopeobject;
typedef struct {
struct ReturnObject *(*binding)(struct ScopeObject *); /**< The function that implements the binding. */
struct returnobject *(*binding)(struct scopeobject *); /**< The function that implements the binding. */
} BindingStmtNode;
/**