basic support for binding to libraries
This commit is contained in:
parent
2014412d5b
commit
38e67f8287
125
binding.c
125
binding.c
|
@ -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;
|
||||
}
|
||||
|
|
16
binding.h
16
binding.h
|
@ -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);
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
2
main.c
|
@ -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) {
|
||||
|
|
6
parser.h
6
parser.h
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue