arrays
Dibyendu Majumdar 4 years ago
parent 352f03ad61
commit bfdb4937b3

@ -1,289 +0,0 @@
#ifndef ravi_ast_h
#define ravi_ast_h
/*
A parser and syntax tree builder for Ravi. This is work in progress.
Once ready it will be used to create a new byte code generator for Ravi.
The parser will perform following actions:
a) Generate syntax tree
b) Perform type checking (Ravi enhancement)
*/
#define LUA_CORE
#include "lprefix.h"
#include "lua.h"
#include "lcode.h"
#include "ldo.h"
#include "lstring.h"
#include "ltable.h"
#include "lauxlib.h"
#include "ravi_ast.h"
#include "ravi_membuf.h"
#include "allocate.h"
#include "ptrlist.h"
#include <assert.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#define MAXVARS 125
//////////////////////////
struct lua_symbol_list;
/*
* Userdata object to hold the abstract syntax tree;
* All memory is held by this object. Memory is freed when
* the object is GC collected; or when
* ast_container:release() method is called
* by user.
*/
struct ast_container {
struct allocator ast_node_allocator;
struct allocator ptrlist_allocator;
struct allocator block_scope_allocator;
struct allocator symbol_allocator;
struct ast_node *main_function;
bool killed; /* flag to check if this is already destroyed */
};
struct ast_node;
DECLARE_PTR_LIST(ast_node_list, struct ast_node);
struct var_type;
DECLARE_PTR_LIST(var_type_list, struct var_type);
/* Lua type info. We need to support user defined types too which are known by name */
struct var_type {
ravitype_t type_code;
const TString *type_name; /* type name for user defined types; used to lookup metatable in registry, only set when
type_code is RAVI_TUSERDATA */
};
struct lua_symbol;
DECLARE_PTR_LIST(lua_symbol_list, struct lua_symbol);
struct block_scope;
/* Types of symbols */
enum symbol_type {
SYM_LOCAL,
SYM_UPVALUE,
SYM_GLOBAL, /* Global symbols are never added to a scope so they are always looked up */
SYM_LABEL
};
/* A symbol is a name recognised in Ravi/Lua code*/
struct lua_symbol {
enum symbol_type symbol_type;
struct var_type value_type;
union {
struct {
const TString *var_name; /* name of the variable */
struct block_scope *block; /* NULL if global symbol, as globals are never added to a scope */
} var;
struct {
const TString *label_name;
struct block_scope *block;
} label;
struct {
struct lua_symbol *var; /* variable reference */
struct ast_node *function; /* Where the upvalue lives */
} upvalue;
};
};
struct block_scope {
struct ast_node *function; /* function owning this block - of type FUNCTION_EXPR */
struct block_scope *parent; /* parent block, may belong to parent function */
struct lua_symbol_list *symbol_list; /* symbols defined in this block */
};
enum ast_node_type {
AST_NONE, /* Used when the node doesn't represent an AST such as test_then_block. */
AST_RETURN_STMT,
AST_GOTO_STMT,
AST_LABEL_STMT,
AST_DO_STMT,
AST_LOCAL_STMT,
AST_FUNCTION_STMT,
AST_IF_STMT,
AST_WHILE_STMT,
AST_FORIN_STMT,
AST_FORNUM_STMT,
AST_REPEAT_STMT,
AST_EXPR_STMT, /* Also used for assignment statements */
AST_LITERAL_EXPR,
AST_SYMBOL_EXPR,
AST_Y_INDEX_EXPR, /* [] operator */
AST_FIELD_SELECTOR_EXPR, /* table field access - '.' or ':' operator */
AST_INDEXED_ASSIGN_EXPR, /* table value assign in table constructor */
AST_SUFFIXED_EXPR,
AST_UNARY_EXPR,
AST_BINARY_EXPR,
AST_FUNCTION_EXPR, /* function literal */
AST_TABLE_EXPR, /* table constructor */
AST_FUNCTION_CALL_EXPR
};
/* The parse tree is made up of ast_node objects. Some of the ast_nodes reference the appropriate block
scopes but not all scopes may be referenced. The tree captures Lua syntax tree - i.e. statements such as
while, repeat, and for are captured in the way user uses them and not the way Lua generates code. Potentially
we can have a transformation step to convert to a tree that is more like the code generation */
struct ast_node {
enum ast_node_type type;
union {
struct {
struct ast_node_list *expr_list;
} return_stmt;
struct {
struct lua_symbol *symbol;
} label_stmt;
struct {
const TString *name; /* target label, used to resolve the goto destination */
struct ast_node *label_stmt; /* Initially this will be NULL; set by a separate pass */
} goto_stmt;
struct {
struct lua_symbol_list *var_list;
struct ast_node_list *expr_list;
} local_stmt; /* local declarations */
struct {
struct ast_node_list *var_expr_list; /* Optional var expressions, comma separated */
struct ast_node_list *expr_list; /* Comma separated expressions */
} expression_stmt; /* Also covers assignments */
struct {
struct ast_node *name; /* base symbol to be looked up */
struct ast_node_list *selectors; /* Optional */
struct ast_node *method_name; /* Optional */
struct ast_node *function_expr; /* Function's AST */
} function_stmt;
struct {
struct block_scope *scope; /* The do statement only creates a new scope */
struct ast_node_list *do_statement_list; /* statements in this block */
} do_stmt;
struct {
struct ast_node *condition;
struct block_scope *test_then_scope;
struct ast_node_list *test_then_statement_list; /* statements in this block */
} test_then_block; /* Used internally in if_stmt, not an independent AST node */
struct {
struct ast_node_list *if_condition_list; /* Actually a list of test_then_blocks */
struct block_scope *else_block;
struct ast_node_list *else_statement_list; /* statements in this block */
} if_stmt;
struct {
struct ast_node *condition;
struct block_scope *loop_scope;
struct ast_node_list *loop_statement_list; /* statements in this block */
} while_or_repeat_stmt;
struct {
struct lua_symbol_list *symbols;
struct ast_node_list *expr_list;
struct block_scope *for_body;
struct ast_node_list *for_statement_list; /* statements in this block */
} for_stmt; /* Used for both generic and numeric for loops */
struct {
struct var_type type;
} common_expr; /* To access the type field common to all expr objects */
/* all expr types must be compatible with common_expr */
struct {
struct var_type type;
union {
lua_Integer i;
lua_Number n;
const TString *s;
} u;
} literal_expr;
struct {
struct var_type type;
struct lua_symbol *var;
} symbol_expr;
struct {
struct var_type type;
struct ast_node *expr; /* '[' expr ']' */
} index_expr;
struct {
struct var_type type;
UnOpr unary_op;
struct ast_node *expr;
} unary_expr;
struct {
struct var_type type;
BinOpr binary_op;
struct ast_node *expr_left;
struct ast_node *expr_right;
} binary_expr;
struct {
struct var_type type;
unsigned int is_vararg : 1;
unsigned int is_method : 1;
struct ast_node *parent_function; /* parent function or NULL if main chunk */
struct block_scope *main_block; /* the function's main block */
struct ast_node_list *function_statement_list; /* statements in this block */
struct lua_symbol_list *args; /* arguments, also must be part of the function block's symbol list */
struct ast_node_list *child_functions; /* child functions declared in this function */
struct lua_symbol_list *upvalues; /* List of upvalues */
struct lua_symbol_list *locals; /* List of locals */
} function_expr; /* a literal expression whose result is a value of type function */
struct {
struct var_type type;
struct ast_node *
index_expr; /* If NULL means this is a list field with next available index, else specfies index expression */
struct ast_node *value_expr;
} indexed_assign_expr; /* Assign values in table constructor */
struct {
struct var_type type;
struct ast_node_list *expr_list;
} table_expr; /* table constructor expression */
struct {
struct var_type type;
struct ast_node *primary_expr;
struct ast_node_list *suffix_list;
} suffixed_expr;
struct {
/* Note that in Ravi the results from a function call must be type asserted during assignment to variables.
* This is not explicit in the AST but is required to ensure that function return values do not
* overwrite the type of the variables in an inconsistent way.
*/
struct var_type type;
TString *method_name; /* Optional method_name */
struct ast_node_list *arg_list; /* Call arguments */
} function_call_expr;
};
};
#define set_typecode(vt, t) \
(vt).type_code = t
#define set_type(vt, t) \
(vt).type_code = t, \
(vt).type_name = NULL
#define set_typename(vt, t, name) \
(vt).type_code = t, \
(vt).type_name = (name)
#define is_type_same(a, b) ((a).type_code == (b).type_code && (a).type_name == (b).type_name)
#define copy_type(a, b) \
(a).type_code = (b).type_code, \
(a).type_name = (b).type_name
struct parser_state {
LexState *ls;
struct ast_container *container;
struct ast_node *current_function;
struct block_scope *current_scope;
};
LUAMOD_API int raviopen_ast_library(lua_State *L);
void raviA_print_ast_node(membuff_t *buf, struct ast_node *node, int level); /* output the AST structure recusrively */
void raviA_ast_typecheck(struct ast_container *container); /* Perform type checks and assign types to AST */
#endif
Loading…
Cancel
Save