You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
590 lines
25 KiB
590 lines
25 KiB
/*
|
|
A compiler for Ravi and Lua 5.3. This is work in progress.
|
|
Once ready it will be used to create a JIT compiler for Ravi.
|
|
|
|
This header file defines the public api
|
|
|
|
Copyright 2018-2020 Dibyendu Majumdar
|
|
*/
|
|
|
|
#ifndef ravicomp_COMPILER_H
|
|
#define ravicomp_COMPILER_H
|
|
|
|
#include "ravicomp_export.h"
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
|
|
typedef struct CompilerState CompilerState;
|
|
typedef struct LexerState LexerState;
|
|
typedef struct LinearizerState LinearizerState;
|
|
typedef struct VariableType VariableType;
|
|
|
|
typedef long long lua_Integer;
|
|
typedef double lua_Number;
|
|
|
|
/* Initialize the compiler state */
|
|
/* During compilation all data structures are stored in the compiler state */
|
|
RAVICOMP_EXPORT CompilerState *raviX_init_compiler(void);
|
|
/* Destroy the compiler state */
|
|
RAVICOMP_EXPORT void raviX_destroy_compiler(CompilerState *compiler);
|
|
|
|
/* ------------------------ LEXICAL ANALYZER API -------------------------------*/
|
|
/* Note: following enum was generate using utils/tokenenum.h */
|
|
enum TokenType {
|
|
TOK_OFS = 256,
|
|
|
|
TOK_and,
|
|
TOK_break,
|
|
TOK_do,
|
|
TOK_else,
|
|
TOK_elseif,
|
|
TOK_end,
|
|
TOK_false,
|
|
TOK_for,
|
|
TOK_function,
|
|
TOK_goto,
|
|
TOK_if,
|
|
TOK_in,
|
|
TOK_local,
|
|
TOK_defer,
|
|
TOK_nil,
|
|
TOK_not,
|
|
TOK_or,
|
|
TOK_repeat,
|
|
TOK_return,
|
|
TOK_then,
|
|
TOK_true,
|
|
TOK_until,
|
|
TOK_while,
|
|
TOK_IDIV,
|
|
TOK_CONCAT,
|
|
TOK_DOTS,
|
|
TOK_EQ,
|
|
TOK_GE,
|
|
TOK_LE,
|
|
TOK_NE,
|
|
TOK_SHL,
|
|
TOK_SHR,
|
|
TOK_DBCOLON,
|
|
TOK_TO_INTEGER,
|
|
TOK_TO_NUMBER,
|
|
TOK_TO_INTARRAY,
|
|
TOK_TO_NUMARRAY,
|
|
TOK_TO_TABLE,
|
|
TOK_TO_STRING,
|
|
TOK_TO_CLOSURE,
|
|
TOK_EOS,
|
|
TOK_FLT,
|
|
TOK_INT,
|
|
TOK_NAME,
|
|
TOK_STRING,
|
|
|
|
FIRST_RESERVED = TOK_OFS + 1,
|
|
LAST_RESERVED = TOK_while - TOK_OFS
|
|
};
|
|
|
|
/*
|
|
* Lua strings can have embedded 0 bytes therefore we
|
|
* need a string type that has a length associated with it.
|
|
*
|
|
* The compiler stores a single copy of each string so that strings
|
|
* can be compared by equality.
|
|
*/
|
|
typedef struct StringObject {
|
|
uint32_t len; /* length of the string */
|
|
int32_t reserved; /* if is this a keyword then token id else -1 */
|
|
uint32_t hash; /* hash value of the string */
|
|
const char *str; /* string data */
|
|
} StringObject;
|
|
|
|
/*
|
|
* Lua literals
|
|
*/
|
|
typedef union {
|
|
lua_Number r;
|
|
lua_Integer i;
|
|
const StringObject *ts;
|
|
} SemInfo;
|
|
|
|
typedef struct Token {
|
|
int token; /* Token value or character value; token values start from FIRST_RESERVED which is 257, values < 256
|
|
are characters */
|
|
SemInfo seminfo; /* Literal associated with the token, only valid when token is a literal or an identifier, i.e.
|
|
token is > TOK_EOS */
|
|
} Token;
|
|
|
|
/*
|
|
* Everything below should be treated as readonly; for efficiency these fields are exposed, however treat them
|
|
* as fields managed by the lexer.
|
|
*/
|
|
typedef struct {
|
|
int current; /* current character (char value as int) */
|
|
int linenumber; /* current input line counter */
|
|
int lastline; /* line number of the last token 'consumed' */
|
|
Token t; /* current token, set after call to raviX_next() */
|
|
Token lookahead; /* look ahead token, set after call to raviX_lookahead() */
|
|
} LexerInfo;
|
|
|
|
/* Following is a dynamic buffer implementation that is not strictly part of the
|
|
* compiler api but is relied upon by various compiler parts. We should perhaps avoid
|
|
* exposing it.
|
|
*
|
|
* The reason for exposing this is that we use it for getting the token string in one of the
|
|
* api calls.
|
|
*/
|
|
typedef struct {
|
|
char *buf; /* pointer to allocated memory, can be reallocated */
|
|
size_t capacity; /* allocated size */
|
|
size_t pos; /* current position in the buffer */
|
|
} TextBuffer;
|
|
|
|
/* all strings are interned and stored in a hash set, strings may have embedded
|
|
* 0 bytes therefore explicit length is necessary
|
|
*/
|
|
RAVICOMP_EXPORT const StringObject *raviX_create_string(CompilerState *compiler_state, const char *s,
|
|
uint32_t len);
|
|
|
|
/* Initialize lexical analyser. Takes as input a buffer containing Lua/Ravi source and the source name */
|
|
RAVICOMP_EXPORT LexerState *raviX_init_lexer(CompilerState *compiler_state, const char *buf,
|
|
size_t buflen, const char *source_name);
|
|
/* Gets the public part of the lexer data structure to allow access the current token. Note that the returned
|
|
* value should be treated as readonly data structure
|
|
*/
|
|
RAVICOMP_EXPORT const LexerInfo *raviX_get_lexer_info(LexerState *ls);
|
|
/* Retrieves the next token and saves it is LexState structure. If a lookahead was set then that is retrieved
|
|
* (and reset to EOS) else the next token is retrieved
|
|
*/
|
|
RAVICOMP_EXPORT void raviX_next(LexerState *ls);
|
|
/* Retrieves the next token and sets it as the lookahead. This means that a next call will get the lookahead.
|
|
* Returns the token id.
|
|
*/
|
|
RAVICOMP_EXPORT int raviX_lookahead(LexerState *ls);
|
|
/* Convert a token to text format. The token will be written to current position in mb. */
|
|
RAVICOMP_EXPORT void raviX_token2str(int token, TextBuffer *mb);
|
|
/* Release all data structures used by the lexer */
|
|
RAVICOMP_EXPORT void raviX_destroy_lexer(LexerState *);
|
|
|
|
/* ---------------- PARSER API -------------------------- */
|
|
|
|
/*
|
|
* Parse a Lua chunk (i.e. script).
|
|
* The Lua chunk will be wrapped in an anonymous Lua function (the 'main' function), so all the code
|
|
* in the chunk will be part of that function. Any functions defined in the chunk will become child functions
|
|
* of the 'main' function.
|
|
*
|
|
* Each Lua chunk / script therefore has an anonymous 'main' function. The name 'main' is just to refer
|
|
* to this function as it has no name in reality.
|
|
*
|
|
* Note that at present a new compiler state should be created when processing a Lua chunk.
|
|
*
|
|
* Returns 0 on success, non-zero on failure.
|
|
*/
|
|
RAVICOMP_EXPORT int raviX_parse(CompilerState *compiler_state, const char *buffer, size_t buflen,
|
|
const char *source_name);
|
|
/* Prints out the AST to the file */
|
|
RAVICOMP_EXPORT void raviX_output_ast(CompilerState *compiler_state, FILE *fp);
|
|
/* Performs type checks on the AST and annotates types of expressions nad variables where possible.
|
|
* As a result the AST will be modified.
|
|
*
|
|
* Returns 0 on success, non-zero on failure.
|
|
*/
|
|
RAVICOMP_EXPORT int
|
|
raviX_ast_typecheck(CompilerState *compiler_state); /* Perform type checks and assign types to AST */
|
|
|
|
/* ---------------------------- LINEARIZER API --------------------------------------- */
|
|
/* linear IR generator.
|
|
* The goal of this component is to convert the AST to a linear IR.
|
|
* This is work in progress, therefore the IR is not yet publicly exposed.
|
|
*/
|
|
RAVICOMP_EXPORT LinearizerState *raviX_init_linearizer(CompilerState *compiler_state);
|
|
/* Attempts to create linear IR for given AST.
|
|
* Returns 0 on success.
|
|
*/
|
|
RAVICOMP_EXPORT int raviX_ast_linearize(LinearizerState *linearizer);
|
|
/* Prints out the content of the linear IR */
|
|
RAVICOMP_EXPORT void raviX_output_linearizer(LinearizerState *linearizer, FILE *fp);
|
|
/* Cleanup the linearizer */
|
|
RAVICOMP_EXPORT void raviX_destroy_linearizer(LinearizerState *linearizer);
|
|
|
|
/* utilies */
|
|
RAVICOMP_EXPORT const char *raviX_get_last_error(CompilerState *compiler_state);
|
|
|
|
/* ----------------------- AST WALKING API ------------------------ */
|
|
|
|
/* Binary operators */
|
|
typedef enum BinaryOperatorType {
|
|
BINOPR_ADD,
|
|
BINOPR_SUB,
|
|
BINOPR_MUL,
|
|
BINOPR_MOD,
|
|
BINOPR_POW,
|
|
BINOPR_DIV,
|
|
BINOPR_IDIV,
|
|
BINOPR_BAND,
|
|
BINOPR_BOR,
|
|
BINOPR_BXOR,
|
|
BINOPR_SHL,
|
|
BINOPR_SHR,
|
|
BINOPR_CONCAT,
|
|
BINOPR_EQ,
|
|
BINOPR_LT,
|
|
BINOPR_LE,
|
|
BINOPR_NE,
|
|
BINOPR_GT,
|
|
BINOPR_GE,
|
|
BINOPR_AND,
|
|
BINOPR_OR,
|
|
BINOPR_NOBINOPR
|
|
} BinaryOperatorType;
|
|
|
|
RAVICOMP_EXPORT const char *raviX_get_binary_opr_str(BinaryOperatorType op);
|
|
|
|
/* Unary operators */
|
|
typedef enum UnaryOperatorType {
|
|
UNOPR_MINUS = BINOPR_NOBINOPR + 1,
|
|
UNOPR_BNOT,
|
|
UNOPR_NOT,
|
|
UNOPR_LEN,
|
|
UNOPR_TO_INTEGER,
|
|
UNOPR_TO_NUMBER,
|
|
UNOPR_TO_INTARRAY,
|
|
UNOPR_TO_NUMARRAY,
|
|
UNOPR_TO_TABLE,
|
|
UNOPR_TO_STRING,
|
|
UNOPR_TO_CLOSURE,
|
|
UNOPR_TO_TYPE,
|
|
UNOPR_NOUNOPR
|
|
} UnaryOperatorType;
|
|
|
|
RAVICOMP_EXPORT const char *raviX_get_unary_opr_str(UnaryOperatorType op);
|
|
|
|
/* Types of AST nodes */
|
|
enum AstNodeType {
|
|
AST_NONE, /* Will never be set on a properly initialized node */
|
|
STMT_RETURN,
|
|
STMT_GOTO,
|
|
STMT_LABEL,
|
|
STMT_DO,
|
|
STMT_LOCAL,
|
|
STMT_FUNCTION,
|
|
STMT_IF,
|
|
STMT_TEST_THEN,
|
|
STMT_WHILE,
|
|
STMT_FOR_IN,
|
|
STMT_FOR_NUM,
|
|
STMT_REPEAT,
|
|
STMT_EXPR, /* Also used for assignment statements */
|
|
EXPR_LITERAL,
|
|
EXPR_SYMBOL,
|
|
EXPR_Y_INDEX, /* [] operator */
|
|
EXPR_FIELD_SELECTOR, /* table field access - '.' or ':' operator */
|
|
EXPR_TABLE_ELEMENT_ASSIGN, /* table element assignment in table constructor */
|
|
EXPR_SUFFIXED,
|
|
EXPR_UNARY,
|
|
EXPR_BINARY,
|
|
EXPR_FUNCTION, /* function literal */
|
|
EXPR_TABLE_LITERAL, /* table constructor */
|
|
EXPR_FUNCTION_CALL
|
|
};
|
|
|
|
typedef struct Statement Statement;
|
|
typedef struct ReturnStatement ReturnStatement;
|
|
typedef struct LabelStatement LabelStatement;
|
|
typedef struct GotoStatement GotoStatement;
|
|
typedef struct LocalStatement LocalStatement;
|
|
typedef struct ExpressionStatement ExpressionStatement;
|
|
typedef struct FunctionStatement FunctionStatement;
|
|
typedef struct DoStatement DoStatement;
|
|
typedef struct TestThenStatement TestThenStatement;
|
|
typedef struct IfStatement IfStatement;
|
|
typedef struct WhileOrRepeatStatement WhileOrRepeatStatement;
|
|
typedef struct ForStatement ForStatement;
|
|
|
|
typedef struct Expression Expression;
|
|
typedef struct LiteralExpression LiteralExpression;
|
|
typedef struct SymbolExpression SymbolExpression;
|
|
typedef struct IndexExpression IndexExpression;
|
|
typedef struct UnaryExpression UnaryExpression;
|
|
typedef struct BinaryExpression BinaryExpression;
|
|
typedef struct FunctionExpression FunctionExpression;
|
|
typedef struct TableElementAssignmentExpression TableElementAssignmentExpression;
|
|
typedef struct TableLiteralExpression TableLiteralExpression;
|
|
typedef struct SuffixedExpression SuffixedExpression;
|
|
typedef struct FunctionCallExpression FunctionCallExpression;
|
|
|
|
typedef struct Scope Scope;
|
|
|
|
/* Types of symbols */
|
|
enum SymbolType {
|
|
SYM_LOCAL, /* lua_variable_symbol */
|
|
SYM_UPVALUE, /* lua_upvalue_symbol */
|
|
SYM_GLOBAL, /* lua_variable_symbol, Global symbols are never added to a scope so they are always looked up */
|
|
SYM_LABEL, /* lua_label_symbol */
|
|
SYM_ENV /* Special symbol type for _ENV */
|
|
};
|
|
typedef struct LuaSymbol LuaSymbol;
|
|
typedef struct LuaUpvalueSymbol LuaUpvalueSymbol;
|
|
typedef struct LuaVariableSymbol LuaVariableSymbol;
|
|
typedef struct LuaLabelSymbol LuaLabelSymbol;
|
|
|
|
/* As described before each parsed Lua script or chunk is wrapped in an anonymous 'main'
|
|
* function hence the AST root is this function.
|
|
*/
|
|
RAVICOMP_EXPORT const FunctionExpression *
|
|
raviX_ast_get_main_function(const CompilerState *compiler_state);
|
|
|
|
/* return statement walking */
|
|
RAVICOMP_EXPORT void raviX_return_statement_foreach_expression(const ReturnStatement *statement, void *userdata,
|
|
void (*callback)(void *, const Expression *expr));
|
|
|
|
/* label statement walking */
|
|
RAVICOMP_EXPORT const StringObject *raviX_label_statement_label_name(const LabelStatement *statement);
|
|
RAVICOMP_EXPORT const Scope *raviX_label_statement_label_scope(const LabelStatement *statement);
|
|
|
|
/* goto statement walking */
|
|
RAVICOMP_EXPORT const StringObject *raviX_goto_statement_label_name(const GotoStatement *statement);
|
|
RAVICOMP_EXPORT const Scope *raviX_goto_statement_scope(const GotoStatement *statement);
|
|
RAVICOMP_EXPORT bool raviX_goto_statement_is_break(const GotoStatement *statement);
|
|
|
|
/* local statement walking */
|
|
RAVICOMP_EXPORT void raviX_local_statement_foreach_expression(const LocalStatement *statement, void *userdata,
|
|
void (*callback)(void *, const Expression *expr));
|
|
RAVICOMP_EXPORT void raviX_local_statement_foreach_symbol(const LocalStatement *statement, void *userdata,
|
|
void (*callback)(void *,
|
|
const LuaVariableSymbol *expr));
|
|
|
|
/* expression or assignment statement walking */
|
|
RAVICOMP_EXPORT void
|
|
raviX_expression_statement_foreach_lhs_expression(const ExpressionStatement *statement, void *userdata,
|
|
void (*callback)(void *, const Expression *expr));
|
|
RAVICOMP_EXPORT void
|
|
raviX_expression_statement_foreach_rhs_expression(const ExpressionStatement *statement, void *userdata,
|
|
void (*callback)(void *, const Expression *expr));
|
|
|
|
/* function statement walking */
|
|
RAVICOMP_EXPORT const SymbolExpression *
|
|
raviX_function_statement_name(const FunctionStatement *statement);
|
|
RAVICOMP_EXPORT bool raviX_function_statement_is_method(const FunctionStatement *statement);
|
|
RAVICOMP_EXPORT const IndexExpression *
|
|
raviX_function_statement_method_name(const FunctionStatement *statement);
|
|
RAVICOMP_EXPORT bool raviX_function_statement_has_selectors(const FunctionStatement *statement);
|
|
RAVICOMP_EXPORT void
|
|
raviX_function_statement_foreach_selector(const FunctionStatement *statement, void *userdata,
|
|
void (*callback)(void *, const IndexExpression *expr));
|
|
RAVICOMP_EXPORT const FunctionExpression *raviX_function_ast(const FunctionStatement *statement);
|
|
|
|
/* do statement walking */
|
|
RAVICOMP_EXPORT const Scope *raviX_do_statement_scope(const DoStatement *statement);
|
|
RAVICOMP_EXPORT void raviX_do_statement_foreach_statement(const DoStatement *statement, void *userdata,
|
|
void (*callback)(void *userdata,
|
|
const Statement *statement));
|
|
/* if statement walking */
|
|
/* Lua if statements are a mix of select/case and if/else statements in
|
|
* other languages. The AST represents the initial if condition block and all subsequent
|
|
* elseif blocks as test_then_statments. The final else block is treated as an optional
|
|
* else block.
|
|
*/
|
|
RAVICOMP_EXPORT void
|
|
raviX_if_statement_foreach_test_then_statement(const IfStatement *statement, void *userdata,
|
|
void (*callback)(void *, const TestThenStatement *stmt));
|
|
RAVICOMP_EXPORT const Scope *raviX_if_then_statement_else_scope(const IfStatement *statement);
|
|
RAVICOMP_EXPORT void raviX_if_statement_foreach_else_statement(const IfStatement *statement, void *userdata,
|
|
void (*callback)(void *userdata,
|
|
const Statement *statement));
|
|
RAVICOMP_EXPORT const Scope *raviX_test_then_statement_scope(const TestThenStatement *statement);
|
|
RAVICOMP_EXPORT void
|
|
raviX_test_then_statement_foreach_statement(const TestThenStatement *statement, void *userdata,
|
|
void (*callback)(void *userdata, const Statement *statement));
|
|
RAVICOMP_EXPORT const Expression *
|
|
raviX_test_then_statement_condition(const TestThenStatement *statement);
|
|
|
|
/* while or repeat statement walking */
|
|
RAVICOMP_EXPORT const Expression *
|
|
raviX_while_or_repeat_statement_condition(const WhileOrRepeatStatement *statement);
|
|
RAVICOMP_EXPORT const Scope *
|
|
raviX_while_or_repeat_statement_scope(const WhileOrRepeatStatement *statement);
|
|
RAVICOMP_EXPORT void
|
|
raviX_while_or_repeat_statement_foreach_statement(const WhileOrRepeatStatement *statement, void *userdata,
|
|
void (*callback)(void *userdata, const Statement *statement));
|
|
|
|
/* for statement walking */
|
|
RAVICOMP_EXPORT const Scope *raviX_for_statement_scope(const ForStatement *statement);
|
|
RAVICOMP_EXPORT void raviX_for_statement_foreach_symbol(const ForStatement *statement, void *userdata,
|
|
void (*callback)(void *,
|
|
const LuaVariableSymbol *expr));
|
|
RAVICOMP_EXPORT void raviX_for_statement_foreach_expression(const ForStatement *statement, void *userdata,
|
|
void (*callback)(void *, const Expression *expr));
|
|
RAVICOMP_EXPORT const Scope *raviX_for_statement_body_scope(const ForStatement *statement);
|
|
RAVICOMP_EXPORT void raviX_for_statement_body_foreach_statement(const ForStatement *statement, void *userdata,
|
|
void (*callback)(void *userdata,
|
|
const Statement *statement));
|
|
|
|
/* literal expression */
|
|
/* Note: '...' value has type RAVI_TVARARGS and no associated SemInfo. */
|
|
RAVICOMP_EXPORT const VariableType *raviX_literal_expression_type(const LiteralExpression *expression);
|
|
RAVICOMP_EXPORT const SemInfo *raviX_literal_expression_literal(const LiteralExpression *expression);
|
|
|
|
/* symbol expression */
|
|
RAVICOMP_EXPORT const VariableType *raviX_symbol_expression_type(const SymbolExpression *expression);
|
|
RAVICOMP_EXPORT const LuaSymbol *raviX_symbol_expression_symbol(const SymbolExpression *expression);
|
|
|
|
/* index expression */
|
|
RAVICOMP_EXPORT const VariableType *raviX_index_expression_type(const IndexExpression *expression);
|
|
RAVICOMP_EXPORT const Expression *raviX_index_expression_expression(const IndexExpression *expression);
|
|
|
|
/* unary expression */
|
|
RAVICOMP_EXPORT const VariableType *raviX_unary_expression_type(const UnaryExpression *expression);
|
|
RAVICOMP_EXPORT const Expression *raviX_unary_expression_expression(const UnaryExpression *expression);
|
|
RAVICOMP_EXPORT UnaryOperatorType raviX_unary_expression_operator(const UnaryExpression *expression);
|
|
|
|
/* binary expression */
|
|
RAVICOMP_EXPORT const VariableType *raviX_binary_expression_type(const BinaryExpression *expression);
|
|
RAVICOMP_EXPORT const Expression *
|
|
raviX_binary_expression_left_expression(const BinaryExpression *expression);
|
|
RAVICOMP_EXPORT const Expression *
|
|
raviX_binary_expression_right_expression(const BinaryExpression *expression);
|
|
RAVICOMP_EXPORT BinaryOperatorType raviX_binary_expression_operator(const BinaryExpression *expression);
|
|
|
|
/* function expression */
|
|
RAVICOMP_EXPORT const VariableType *raviX_function_type(const FunctionExpression *function_expression);
|
|
RAVICOMP_EXPORT bool raviX_function_is_vararg(const FunctionExpression *function_expression);
|
|
RAVICOMP_EXPORT bool raviX_function_is_method(const FunctionExpression *function_expression);
|
|
RAVICOMP_EXPORT const FunctionExpression *
|
|
raviX_function_parent(const FunctionExpression *function_expression);
|
|
RAVICOMP_EXPORT void
|
|
raviX_function_foreach_child(const FunctionExpression *function_expression, void *userdata,
|
|
void (*callback)(void *userdata, const FunctionExpression *function_expression));
|
|
RAVICOMP_EXPORT const Scope *raviX_function_scope(const FunctionExpression *function_expression);
|
|
RAVICOMP_EXPORT void
|
|
raviX_function_foreach_statement(const FunctionExpression *function_expression, void *userdata,
|
|
void (*callback)(void *userdata, const Statement *statement));
|
|
RAVICOMP_EXPORT void
|
|
raviX_function_foreach_argument(const FunctionExpression *function_expression, void *userdata,
|
|
void (*callback)(void *userdata, const LuaVariableSymbol *symbol));
|
|
RAVICOMP_EXPORT void raviX_function_foreach_local(const FunctionExpression *function_expression, void *userdata,
|
|
void (*callback)(void *userdata,
|
|
const LuaVariableSymbol *lua_local_symbol));
|
|
RAVICOMP_EXPORT void
|
|
raviX_function_foreach_upvalue(const FunctionExpression *function_expression, void *userdata,
|
|
void (*callback)(void *userdata, const LuaUpvalueSymbol *symbol));
|
|
|
|
/* table element assignment expression */
|
|
RAVICOMP_EXPORT const VariableType *
|
|
raviX_table_element_assignment_expression_type(const TableElementAssignmentExpression *expression);
|
|
RAVICOMP_EXPORT const Expression *
|
|
raviX_table_element_assignment_expression_key(const TableElementAssignmentExpression *expression);
|
|
RAVICOMP_EXPORT const Expression *
|
|
raviX_table_element_assignment_expression_value(const TableElementAssignmentExpression *expression);
|
|
|
|
/* table_literal_expression */
|
|
RAVICOMP_EXPORT const VariableType *
|
|
raviX_table_literal_expression_type(const TableLiteralExpression *expression);
|
|
RAVICOMP_EXPORT void raviX_table_literal_expression_foreach_element(
|
|
const TableLiteralExpression *expression, void *userdata,
|
|
void (*callback)(void *, const TableElementAssignmentExpression *expr));
|
|
|
|
/* suffixed_expression */
|
|
RAVICOMP_EXPORT const VariableType *raviX_suffixed_expression_type(const SuffixedExpression *expression);
|
|
RAVICOMP_EXPORT const Expression *
|
|
raviX_suffixed_expression_primary(const SuffixedExpression *expression);
|
|
RAVICOMP_EXPORT void raviX_suffixed_expression_foreach_suffix(const SuffixedExpression *expression,
|
|
void *userdata,
|
|
void (*callback)(void *, const Expression *expr));
|
|
|
|
/* function call expression */
|
|
RAVICOMP_EXPORT const VariableType *
|
|
raviX_function_call_expression_type(const FunctionCallExpression *expression);
|
|
// can return NULL
|
|
RAVICOMP_EXPORT const StringObject *
|
|
raviX_function_call_expression_method_name(const FunctionCallExpression *expression);
|
|
RAVICOMP_EXPORT void
|
|
raviX_function_call_expression_foreach_argument(const FunctionCallExpression *expression, void *userdata,
|
|
void (*callback)(void *, const Expression *expr));
|
|
|
|
/* Convert a statement to the correct type */
|
|
RAVICOMP_EXPORT enum AstNodeType raviX_statement_type(const Statement *statement);
|
|
RAVICOMP_EXPORT const ReturnStatement *raviX_return_statement(const Statement *stmt);
|
|
RAVICOMP_EXPORT const LabelStatement *raviX_label_statement(const Statement *stmt);
|
|
RAVICOMP_EXPORT const GotoStatement *raviX_goto_statement(const Statement *stmt);
|
|
RAVICOMP_EXPORT const LocalStatement *raviX_local_statement(const Statement *stmt);
|
|
RAVICOMP_EXPORT const ExpressionStatement *raviX_expression_statement(const Statement *stmt);
|
|
RAVICOMP_EXPORT const FunctionStatement *raviX_function_statement(const Statement *stmt);
|
|
RAVICOMP_EXPORT const DoStatement *raviX_do_statement(const Statement *stmt);
|
|
RAVICOMP_EXPORT const TestThenStatement *raviX_test_then_statement(const Statement *stmt);
|
|
RAVICOMP_EXPORT const IfStatement *raviX_if_statement(const Statement *stmt);
|
|
RAVICOMP_EXPORT const WhileOrRepeatStatement *raviX_while_or_repeat_statement(const Statement *stmt);
|
|
RAVICOMP_EXPORT const ForStatement *raviX_for_statement(const Statement *stmt);
|
|
|
|
/* Convert an expression to the correct type */
|
|
RAVICOMP_EXPORT enum AstNodeType raviX_expression_type(const Expression *expression);
|
|
RAVICOMP_EXPORT const LiteralExpression *raviX_literal_expression(const Expression *expr);
|
|
RAVICOMP_EXPORT const SymbolExpression *raviX_symbol_expression(const Expression *expr);
|
|
RAVICOMP_EXPORT const IndexExpression *raviX_index_expression(const Expression *expr);
|
|
RAVICOMP_EXPORT const UnaryExpression *raviX_unary_expression(const Expression *expr);
|
|
RAVICOMP_EXPORT const BinaryExpression *raviX_binary_expression(const Expression *expr);
|
|
RAVICOMP_EXPORT const FunctionExpression *raviX_function_expression(const Expression *expr);
|
|
RAVICOMP_EXPORT const TableElementAssignmentExpression *
|
|
raviX_table_element_assignment_expression(const Expression *expr);
|
|
RAVICOMP_EXPORT const TableLiteralExpression *raviX_table_literal_expression(const Expression *expr);
|
|
RAVICOMP_EXPORT const SuffixedExpression *raviX_suffixed_expression(const Expression *expr);
|
|
RAVICOMP_EXPORT const FunctionCallExpression *raviX_function_call_expression(const Expression *expr);
|
|
|
|
RAVICOMP_EXPORT const FunctionExpression *raviX_scope_owning_function(const Scope *scope);
|
|
RAVICOMP_EXPORT const Scope *raviX_scope_parent_scope(const Scope *scope);
|
|
RAVICOMP_EXPORT void raviX_scope_foreach_symbol(const Scope *scope, void *userdata,
|
|
void (*callback)(void *userdata, const LuaSymbol *symbol));
|
|
|
|
RAVICOMP_EXPORT enum SymbolType raviX_symbol_type(const LuaSymbol *symbol);
|
|
/* symbol downcast */
|
|
RAVICOMP_EXPORT const LuaVariableSymbol *raviX_symbol_variable(const LuaSymbol *symbol);
|
|
RAVICOMP_EXPORT const LuaUpvalueSymbol *raviX_symbol_upvalue(const LuaSymbol *symbol);
|
|
RAVICOMP_EXPORT const LuaLabelSymbol *raviX_symbol_label(const LuaSymbol *symbol);
|
|
|
|
/* variable symbol - local and global variables */
|
|
RAVICOMP_EXPORT const StringObject *
|
|
raviX_variable_symbol_name(const LuaVariableSymbol *lua_local_symbol);
|
|
RAVICOMP_EXPORT const VariableType *raviX_variable_symbol_type(const LuaVariableSymbol *lua_local_symbol);
|
|
// NULL if global
|
|
RAVICOMP_EXPORT const Scope *
|
|
raviX_variable_symbol_scope(const LuaVariableSymbol *lua_local_symbol);
|
|
|
|
/* label symbol */
|
|
RAVICOMP_EXPORT const StringObject *raviX_label_name(const LuaLabelSymbol *symbol);
|
|
RAVICOMP_EXPORT const Scope *raviX_label_scope(const LuaLabelSymbol *symbol);
|
|
|
|
/* upvalue symbol */
|
|
RAVICOMP_EXPORT const VariableType *raviX_upvalue_symbol_type(const LuaUpvalueSymbol *symbol);
|
|
RAVICOMP_EXPORT const LuaVariableSymbol *
|
|
raviX_upvalue_target_variable(const LuaUpvalueSymbol *symbol);
|
|
RAVICOMP_EXPORT const FunctionExpression *
|
|
raviX_upvalue_target_function(const LuaUpvalueSymbol *symbol);
|
|
RAVICOMP_EXPORT unsigned raviX_upvalue_index(const LuaUpvalueSymbol *symbol);
|
|
|
|
/* Utilities */
|
|
#ifdef __GNUC__
|
|
#define FORMAT_ATTR(pos) __attribute__((__format__(__printf__, pos, pos + 1)))
|
|
#else
|
|
#define FORMAT_ATTR(pos)
|
|
#endif
|
|
|
|
RAVICOMP_EXPORT void raviX_buffer_init(TextBuffer *mb, size_t initial_size);
|
|
RAVICOMP_EXPORT void raviX_buffer_resize(TextBuffer *mb, size_t new_size);
|
|
RAVICOMP_EXPORT void raviX_buffer_reserve(TextBuffer *mb, size_t n);
|
|
RAVICOMP_EXPORT void raviX_buffer_free(TextBuffer *mb);
|
|
static inline char *raviX_buffer_data(const TextBuffer *mb) { return mb->buf; }
|
|
static inline size_t raviX_buffer_size(const TextBuffer *mb) { return mb->capacity; }
|
|
static inline size_t raviX_buffer_len(const TextBuffer *mb) { return mb->pos; }
|
|
static inline void raviX_buffer_reset(TextBuffer *mb) { mb->pos = 0; }
|
|
|
|
/* following convert input to string before adding */
|
|
RAVICOMP_EXPORT void raviX_buffer_add_string(TextBuffer *mb, const char *str);
|
|
RAVICOMP_EXPORT void raviX_buffer_add_bytes(TextBuffer *mb, const char *str, size_t len);
|
|
RAVICOMP_EXPORT void raviX_buffer_add_fstring(TextBuffer *mb, const char *str, ...) FORMAT_ATTR(2);
|
|
|
|
/* strncpy() replacement with guaranteed 0 termination */
|
|
RAVICOMP_EXPORT void raviX_string_copy(char *buf, const char *src, size_t buflen);
|
|
|
|
#endif
|