barely working bindings

This commit is contained in:
Justin Meza 2013-02-23 19:51:07 -05:00
parent 5751d3fd42
commit 2014412d5b
7 changed files with 178 additions and 5 deletions

View File

@ -28,6 +28,7 @@ SET(HDRS
tokenizer.h
unicode.h
error.h
binding.h
)
SET(SRCS
@ -38,6 +39,7 @@ SET(SRCS
tokenizer.c
unicode.c
error.c
binding.c
)
add_executable(lci ${SRCS} ${HDRS})

43
binding.c Normal file
View File

@ -0,0 +1,43 @@
#include "binding.h"
struct returnobject;
struct scopeobject;
struct returnobject *fopenWrapper(struct scopeobject *scope)
{
fprintf(stderr, "HERE\n");
}
void loadBinding(ScopeObject *scope)
{
/* TODO: add error checking and handling */
/* stdio */
Binding *fopen = malloc(sizeof(Binding));
fopen->library = createIdentifierNode(IT_DIRECT, (void *)copyString("STDIO"), NULL, NULL, 0);
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);
createScopeValue(scope, scope, name);
updateScopeValue(scope, scope, name, val);
return;
loadBindingAbort: /* Exception handling */
return;
}

49
binding.h Normal file
View File

@ -0,0 +1,49 @@
/**
* Structures and functions for binding to external libraries.
*
* \file binding.h
*
* \author Justin J. Meza
*
* \date 2013
*/
#ifndef __BINDING_H__
#define __BINDING_H__
#include <stdio.h>
#include "interpreter.h"
/**
* 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. */
} Binding;
void loadBinding(ScopeObject *); /* TODO: make this take an IdentifierNode library to load */
/**
* TODO:
* - At startup, check which bindings are imported (using "CAN HAS" syntax)
* - Package those bindings as VT_FUNCs in BUKKITs
* - Add those bindings to the top-level scope (maybe create a new,
* higher-than-global scope for this)
* - To implement a new binding, specify the interface, which will contain a
* BlockNode that contains a StmtListNode with one statement: a
* BindingStmtNode that implements a native function that modifies directly
* 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);
*/
#endif /* __BINDING_H__ */

View File

@ -3589,7 +3589,7 @@ ReturnObject *interpretExprStmtNode(StmtNode *node,
*
* \param [in] scope The scope to evaluate \a node under.
*
* \pre \a node contains a statement created by createAltArrayDefNode().
* \pre \a node contains a statement created by createAltArrayDefStmtNode().
*
* \return A pointer to a default return value.
*
@ -3639,11 +3639,31 @@ ReturnObject *interpretAltArrayDefStmtNode(StmtNode *node,
return createReturnObject(RT_DEFAULT, NULL);
}
/**
* Interprets a binding statement.
*
* \param [in] node The statement to interpret.
*
* \param [in] scope The scope to evaluate \a node under.
*
* \pre \a node contains a statement created by createBindingStmtNode().
*
* \return A pointer to a default return value.
*
* \retval NULL An error occurred during interpretation.
*/
ReturnObject *interpretBindingStmtNode(StmtNode *node,
ScopeObject *scope)
{
BindingStmtNode *stmt = (BindingStmtNode *)node->stmt;
return (stmt->binding)(scope);
}
/*
* A jump table for statements. The index of a function in the table is given
* by its its index in the enumerated StmtType type.
*/
static ReturnObject *(*StmtJumpTable[14])(StmtNode *, ScopeObject *) = {
static ReturnObject *(*StmtJumpTable[15])(StmtNode *, ScopeObject *) = {
interpretCastStmtNode,
interpretPrintStmtNode,
interpretInputStmtNode,
@ -3657,7 +3677,8 @@ static ReturnObject *(*StmtJumpTable[14])(StmtNode *, ScopeObject *) = {
interpretDeallocationStmtNode,
interpretFuncDefStmtNode,
interpretExprStmtNode,
interpretAltArrayDefStmtNode };
interpretAltArrayDefStmtNode,
interpretBindingStmtNode };
/**
* Interprets a statement.
@ -3753,7 +3774,10 @@ int interpretMainNode(MainNode *main)
{
ReturnObject *ret = NULL;
if (!main) return 1;
ret = interpretBlockNode(main->block, NULL);
ScopeObject *libs = createScopeObject(NULL);
if (!libs) return 1;
loadBinding(libs);
ret = interpretBlockNode(main->block, libs);
if (!ret) return 1;
deleteReturnObject(ret);
return 0;

View File

@ -101,7 +101,7 @@ typedef enum {
/**
* Stores return state.
*/
typedef struct {
typedef struct returnobject {
ReturnType type; /**< The type of return encountered. */
ValueObject *value; /**< The optional return value. */
} ReturnObject;

View File

@ -1105,6 +1105,39 @@ void deleteAltArrayDefStmtNode(AltArrayDefStmtNode *node)
free(node);
}
/**
* Creates a binding statement.
*
* \param [in] binding A pointer to the function that defines the binding.
*
* \return A pointer to a binding statement with the desired properties.
*
* \retval NULL Memory allocation failed.
*/
BindingStmtNode *createBindingStmtNode(struct returnobject *(*binding)(struct scopeobject *))
{
BindingStmtNode *p = malloc(sizeof(BindingStmtNode));
if (!p) {
perror("malloc");
return NULL;
}
p->binding = binding;
return p;
}
/**
* Deletes a binding statement.
*
* \param [in,out] node The binding statement to delete.
*
* \post The memory at \a node and all of its members will be freed.
*/
void deleteBindingStmtNode(BindingStmtNode *node)
{
if (!node) return;
free(node);
}
/**
* Creates an expression.
*

View File

@ -228,6 +228,7 @@ typedef enum {
ST_FUNCDEF, /**< Function definition statement. */
ST_EXPR, /**< Expression statement. */
ST_ALTARRAYDEF, /**< Function definition statement. */
ST_BINDING, /**< Binding to external library. */
} StmtType;
/**
@ -364,6 +365,15 @@ typedef struct {
IdentifierNode *parent; /**< An optional inherited array. */
} AltArrayDefStmtNode;
/**
* Stores a binding to a native function.
*/
struct ReturnObject;
struct ScopeObject;
typedef struct {
struct ReturnObject *(*binding)(struct ScopeObject *); /**< The function that implements the binding. */
} BindingStmtNode;
/**
* Stores the main code block of a program.
*
@ -716,6 +726,18 @@ AltArrayDefStmtNode *createAltArrayDefStmtNode(IdentifierNode *, BlockNode *, Id
void deleteAltArrayDefStmtNode(AltArrayDefStmtNode *);
/**@}*/
/**
* \name BindingStmtNode modifiers
*
* Functions for creating and deleting BindingStmtNodes.
*/
/**@{*/
struct returnobject;
struct scopeobject;
BindingStmtNode *createBindingStmtNode(struct returnobject *(*binding)(struct scopeobject *));
void deleteBindingStmtNode(BindingStmtNode *);
/**@}*/
/**
* \name ExprNode modifiers
*