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.
640 lines
22 KiB
640 lines
22 KiB
/******************************************************************************
|
|
* Copyright (C) 2020-2021 Dibyendu Majumdar
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
* a copy of this software and associated documentation files (the
|
|
* "Software"), to deal in the Software without restriction, including
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
* the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be
|
|
* included in all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
******************************************************************************/
|
|
#include <ravi_compiler.h>
|
|
|
|
#include <parser.h>
|
|
|
|
const FunctionExpression *raviX_ast_get_main_function(const CompilerState *compiler_state)
|
|
{
|
|
return &compiler_state->main_function->function_expr;
|
|
}
|
|
const VariableType *raviX_function_type(const FunctionExpression *function_expression)
|
|
{
|
|
return &function_expression->type;
|
|
}
|
|
bool raviX_function_is_vararg(const FunctionExpression *function_expression)
|
|
{
|
|
return function_expression->is_vararg;
|
|
}
|
|
bool raviX_function_is_method(const FunctionExpression *function_expression)
|
|
{
|
|
return function_expression->is_method;
|
|
}
|
|
const FunctionExpression *raviX_function_parent(const FunctionExpression *function_expression)
|
|
{
|
|
if (function_expression->parent_function == NULL)
|
|
return NULL;
|
|
else
|
|
return &function_expression->parent_function->function_expr;
|
|
}
|
|
void raviX_function_foreach_child(const FunctionExpression *function_expression, void *userdata,
|
|
void (*callback)(void *userdata,
|
|
const FunctionExpression *function_expression))
|
|
{
|
|
AstNode *node;
|
|
FOR_EACH_PTR(function_expression->child_functions, AstNode, node) { callback(userdata, &node->function_expr); }
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
const Scope *raviX_function_scope(const FunctionExpression *function_expression)
|
|
{
|
|
return function_expression->main_block;
|
|
}
|
|
void raviX_function_foreach_statement(const FunctionExpression *function_expression, void *userdata,
|
|
void (*callback)(void *userdata, const Statement *statement))
|
|
{
|
|
AstNode *node;
|
|
FOR_EACH_PTR(function_expression->function_statement_list, AstNode, node)
|
|
{
|
|
assert(node->type <= STMT_EXPR);
|
|
callback(userdata, (Statement *)node);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
enum AstNodeType raviX_statement_type(const Statement *statement) { return statement->type; }
|
|
void raviX_function_foreach_argument(const FunctionExpression *function_expression, void *userdata,
|
|
void (*callback)(void *userdata, const LuaVariableSymbol *symbol))
|
|
{
|
|
LuaSymbol *symbol;
|
|
FOR_EACH_PTR(function_expression->args, LuaSymbol, symbol) { callback(userdata, &symbol->variable); }
|
|
END_FOR_EACH_PTR(symbol)
|
|
}
|
|
void raviX_function_foreach_local(const FunctionExpression *function_expression, void *userdata,
|
|
void (*callback)(void *userdata, const LuaVariableSymbol *lua_local_symbol))
|
|
{
|
|
LuaSymbol *symbol;
|
|
FOR_EACH_PTR(function_expression->locals, LuaSymbol, symbol) { callback(userdata, &symbol->variable); }
|
|
END_FOR_EACH_PTR(symbol)
|
|
}
|
|
void raviX_function_foreach_upvalue(const FunctionExpression *function_expression, void *userdata,
|
|
void (*callback)(void *userdata, const LuaUpvalueSymbol *symbol))
|
|
{
|
|
LuaSymbol *symbol;
|
|
FOR_EACH_PTR(function_expression->upvalues, LuaSymbol, symbol) { callback(userdata, &symbol->upvalue); }
|
|
END_FOR_EACH_PTR(symbol)
|
|
}
|
|
|
|
const StringObject *raviX_variable_symbol_name(const LuaVariableSymbol *lua_local_symbol)
|
|
{
|
|
return lua_local_symbol->var_name;
|
|
}
|
|
|
|
const VariableType *raviX_variable_symbol_type(const LuaVariableSymbol *lua_local_symbol)
|
|
{
|
|
return &lua_local_symbol->value_type;
|
|
}
|
|
|
|
const Scope *raviX_variable_symbol_scope(const LuaVariableSymbol *lua_local_symbol)
|
|
{
|
|
return lua_local_symbol->block;
|
|
}
|
|
|
|
#define n(v) ((AstNode *)v)
|
|
const ReturnStatement *raviX_return_statement(const Statement *stmt)
|
|
{
|
|
assert(stmt->type == STMT_RETURN);
|
|
return &n(stmt)->return_stmt;
|
|
}
|
|
const LabelStatement *raviX_label_statement(const Statement *stmt)
|
|
{
|
|
assert(stmt->type == STMT_LABEL);
|
|
return &n(stmt)->label_stmt;
|
|
}
|
|
const GotoStatement *raviX_goto_statement(const Statement *stmt)
|
|
{
|
|
assert(stmt->type == STMT_GOTO);
|
|
return &n(stmt)->goto_stmt;
|
|
}
|
|
const LocalStatement *raviX_local_statement(const Statement *stmt)
|
|
{
|
|
assert(stmt->type == STMT_LOCAL);
|
|
return &n(stmt)->local_stmt;
|
|
}
|
|
const ExpressionStatement *raviX_expression_statement(const Statement *stmt)
|
|
{
|
|
assert(stmt->type == STMT_EXPR);
|
|
return &n(stmt)->expression_stmt;
|
|
}
|
|
const FunctionStatement *raviX_function_statement(const Statement *stmt)
|
|
{
|
|
assert(stmt->type == STMT_FUNCTION);
|
|
return &n(stmt)->function_stmt;
|
|
}
|
|
const DoStatement *raviX_do_statement(const Statement *stmt)
|
|
{
|
|
assert(stmt->type == STMT_DO);
|
|
return &n(stmt)->do_stmt;
|
|
}
|
|
const TestThenStatement *raviX_test_then_statement(const Statement *stmt)
|
|
{
|
|
assert(stmt->type == STMT_TEST_THEN);
|
|
return &n(stmt)->test_then_block;
|
|
}
|
|
const IfStatement *raviX_if_statement(const Statement *stmt)
|
|
{
|
|
assert(stmt->type == STMT_IF);
|
|
return &n(stmt)->if_stmt;
|
|
}
|
|
const WhileOrRepeatStatement *raviX_while_or_repeat_statement(const Statement *stmt)
|
|
{
|
|
assert(stmt->type == STMT_WHILE || stmt->type == STMT_REPEAT);
|
|
return &n(stmt)->while_or_repeat_stmt;
|
|
}
|
|
const ForStatement *raviX_for_statement(const Statement *stmt)
|
|
{
|
|
assert(stmt->type == STMT_FOR_IN || stmt->type == STMT_FOR_NUM);
|
|
return &n(stmt)->for_stmt;
|
|
}
|
|
enum AstNodeType raviX_expression_type(const Expression *expression) { return expression->type; }
|
|
const LiteralExpression *raviX_literal_expression(const Expression *expr)
|
|
{
|
|
assert(expr->type == EXPR_LITERAL);
|
|
return &n(expr)->literal_expr;
|
|
}
|
|
const SymbolExpression *raviX_symbol_expression(const Expression *expr)
|
|
{
|
|
assert(expr->type == EXPR_SYMBOL);
|
|
return &n(expr)->symbol_expr;
|
|
}
|
|
const IndexExpression *raviX_index_expression(const Expression *expr)
|
|
{
|
|
assert(expr->type == EXPR_Y_INDEX || expr->type == EXPR_FIELD_SELECTOR);
|
|
return &n(expr)->index_expr;
|
|
}
|
|
const UnaryExpression *raviX_unary_expression(const Expression *expr)
|
|
{
|
|
assert(expr->type == EXPR_UNARY);
|
|
return &n(expr)->unary_expr;
|
|
}
|
|
const BinaryExpression *raviX_binary_expression(const Expression *expr)
|
|
{
|
|
assert(expr->type == EXPR_BINARY);
|
|
return &n(expr)->binary_expr;
|
|
}
|
|
const FunctionExpression *raviX_function_expression(const Expression *expr)
|
|
{
|
|
assert(expr->type == EXPR_FUNCTION);
|
|
return &n(expr)->function_expr;
|
|
}
|
|
const TableElementAssignmentExpression *
|
|
raviX_table_element_assignment_expression(const Expression *expr)
|
|
{
|
|
assert(expr->type == EXPR_TABLE_ELEMENT_ASSIGN);
|
|
return &n(expr)->table_elem_assign_expr;
|
|
}
|
|
const TableLiteralExpression *raviX_table_literal_expression(const Expression *expr)
|
|
{
|
|
assert(expr->type == EXPR_TABLE_LITERAL);
|
|
return &n(expr)->table_expr;
|
|
}
|
|
const SuffixedExpression *raviX_suffixed_expression(const Expression *expr)
|
|
{
|
|
assert(expr->type == EXPR_SUFFIXED);
|
|
return &n(expr)->suffixed_expr;
|
|
}
|
|
const FunctionCallExpression *raviX_function_call_expression(const Expression *expr)
|
|
{
|
|
assert(expr->type == EXPR_FUNCTION_CALL);
|
|
return &n(expr)->function_call_expr;
|
|
}
|
|
#undef n
|
|
|
|
void raviX_return_statement_foreach_expression(const ReturnStatement *statement, void *userdata,
|
|
void (*callback)(void *, const Expression *expr))
|
|
{
|
|
AstNode *node;
|
|
FOR_EACH_PTR(statement->expr_list, AstNode, node)
|
|
{
|
|
assert(node->type >= EXPR_LITERAL && node->type <= EXPR_FUNCTION_CALL);
|
|
callback(userdata, (Expression *)node);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
|
|
const StringObject *raviX_label_statement_label_name(const LabelStatement *statement)
|
|
{
|
|
return statement->symbol->label.label_name;
|
|
}
|
|
const Scope *raviX_label_statement_label_scope(const LabelStatement *statement)
|
|
{
|
|
return statement->symbol->label.block;
|
|
}
|
|
|
|
const StringObject *raviX_goto_statement_label_name(const GotoStatement *statement)
|
|
{
|
|
return statement->name;
|
|
}
|
|
const Scope *raviX_goto_statement_scope(const GotoStatement *statement)
|
|
{
|
|
return statement->goto_scope;
|
|
}
|
|
bool raviX_goto_statement_is_break(const GotoStatement *statement) { return statement->is_break; }
|
|
|
|
void raviX_local_statement_foreach_expression(const LocalStatement *statement, void *userdata,
|
|
void (*callback)(void *, const Expression *expr))
|
|
{
|
|
AstNode *node;
|
|
FOR_EACH_PTR(statement->expr_list, AstNode, node)
|
|
{
|
|
assert(node->type >= EXPR_LITERAL && node->type <= EXPR_FUNCTION_CALL);
|
|
callback(userdata, (Expression *)node);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
void raviX_local_statement_foreach_symbol(const LocalStatement *statement, void *userdata,
|
|
void (*callback)(void *, const LuaVariableSymbol *expr))
|
|
{
|
|
LuaSymbol *symbol;
|
|
FOR_EACH_PTR(statement->var_list, LuaSymbol, symbol)
|
|
{
|
|
assert(symbol->symbol_type == SYM_LOCAL);
|
|
callback(userdata, &symbol->variable);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
void raviX_expression_statement_foreach_lhs_expression(const ExpressionStatement *statement, void *userdata,
|
|
void (*callback)(void *, const Expression *expr))
|
|
{
|
|
AstNode *node;
|
|
FOR_EACH_PTR(statement->var_expr_list, AstNode, node)
|
|
{
|
|
assert(node->type >= EXPR_LITERAL && node->type <= EXPR_FUNCTION_CALL);
|
|
callback(userdata, (Expression *)node);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
void raviX_expression_statement_foreach_rhs_expression(const ExpressionStatement *statement, void *userdata,
|
|
void (*callback)(void *, const Expression *expr))
|
|
{
|
|
AstNode *node;
|
|
FOR_EACH_PTR(statement->expr_list, AstNode, node)
|
|
{
|
|
assert(node->type >= EXPR_LITERAL && node->type <= EXPR_FUNCTION_CALL);
|
|
callback(userdata, (Expression *)node);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
const SymbolExpression *raviX_function_statement_name(const FunctionStatement *statement)
|
|
{
|
|
assert(statement->name->type == EXPR_SYMBOL);
|
|
return &statement->name->symbol_expr;
|
|
}
|
|
bool raviX_function_statement_is_method(const FunctionStatement *statement)
|
|
{
|
|
return statement->method_name != NULL;
|
|
}
|
|
const IndexExpression *raviX_function_statement_method_name(const FunctionStatement *statement)
|
|
{
|
|
assert(statement->method_name->type == EXPR_Y_INDEX || statement->method_name->type == EXPR_FIELD_SELECTOR);
|
|
return &statement->method_name->index_expr;
|
|
}
|
|
bool raviX_function_statement_has_selectors(const FunctionStatement *statement)
|
|
{
|
|
return statement->selectors != NULL;
|
|
}
|
|
void raviX_function_statement_foreach_selector(const FunctionStatement *statement, void *userdata,
|
|
void (*callback)(void *, const IndexExpression *expr))
|
|
{
|
|
AstNode *node;
|
|
FOR_EACH_PTR(statement->selectors, AstNode, node)
|
|
{
|
|
assert(node->type == EXPR_Y_INDEX || node->type == EXPR_FIELD_SELECTOR);
|
|
callback(userdata, &node->index_expr);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
const FunctionExpression *raviX_function_ast(const FunctionStatement *statement)
|
|
{
|
|
assert(statement->function_expr->type == EXPR_FUNCTION);
|
|
return &statement->function_expr->function_expr;
|
|
}
|
|
const Scope *raviX_do_statement_scope(const DoStatement *statement) { return statement->scope; }
|
|
void raviX_do_statement_foreach_statement(const DoStatement *statement, void *userdata,
|
|
void (*callback)(void *userdata, const Statement *statement))
|
|
{
|
|
AstNode *node;
|
|
FOR_EACH_PTR(statement->do_statement_list, AstNode, node)
|
|
{
|
|
assert(node->type <= STMT_EXPR);
|
|
callback(userdata, (Statement *)node);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
const Scope *raviX_test_then_statement_scope(const TestThenStatement *statement)
|
|
{
|
|
return statement->test_then_scope;
|
|
}
|
|
void raviX_test_then_statement_foreach_statement(const TestThenStatement *statement, void *userdata,
|
|
void (*callback)(void *userdata, const Statement *statement))
|
|
{
|
|
AstNode *node;
|
|
FOR_EACH_PTR(statement->test_then_statement_list, AstNode, node)
|
|
{
|
|
assert(node->type <= STMT_EXPR);
|
|
callback(userdata, (Statement *)node);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
const Expression *raviX_test_then_statement_condition(const TestThenStatement *statement)
|
|
{
|
|
assert(statement->condition->type >= EXPR_LITERAL && statement->condition->type <= EXPR_FUNCTION_CALL);
|
|
return (Expression *)statement->condition;
|
|
}
|
|
void raviX_if_statement_foreach_test_then_statement(const IfStatement *statement, void *userdata,
|
|
void (*callback)(void *, const TestThenStatement *stmt))
|
|
{
|
|
AstNode *node;
|
|
FOR_EACH_PTR(statement->if_condition_list, AstNode, node)
|
|
{
|
|
assert(node->type == STMT_TEST_THEN);
|
|
callback(userdata, &node->test_then_block);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
const Scope *raviX_if_then_statement_else_scope(const IfStatement *statement)
|
|
{
|
|
return statement->else_block;
|
|
}
|
|
void raviX_if_statement_foreach_else_statement(const IfStatement *statement, void *userdata,
|
|
void (*callback)(void *userdata, const Statement *statement))
|
|
{
|
|
AstNode *node;
|
|
FOR_EACH_PTR(statement->else_statement_list, AstNode, node)
|
|
{
|
|
assert(node->type <= STMT_EXPR);
|
|
callback(userdata, (Statement *)node);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
|
|
const Expression *raviX_while_or_repeat_statement_condition(const WhileOrRepeatStatement *statement)
|
|
{
|
|
assert(statement->condition->type >= EXPR_LITERAL && statement->condition->type <= EXPR_FUNCTION_CALL);
|
|
return (Expression *)statement->condition;
|
|
}
|
|
const Scope *raviX_while_or_repeat_statement_scope(const WhileOrRepeatStatement *statement)
|
|
{
|
|
return statement->loop_scope;
|
|
}
|
|
void raviX_while_or_repeat_statement_foreach_statement(const WhileOrRepeatStatement *statement,
|
|
void *userdata,
|
|
void (*callback)(void *userdata,
|
|
const Statement *statement))
|
|
{
|
|
AstNode *node;
|
|
FOR_EACH_PTR(statement->loop_statement_list, AstNode, node)
|
|
{
|
|
assert(node->type <= STMT_EXPR);
|
|
callback(userdata, (Statement *)node);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
const Scope *raviX_for_statement_scope(const ForStatement *statement)
|
|
{
|
|
return statement->for_scope;
|
|
}
|
|
void raviX_for_statement_foreach_symbol(const ForStatement *statement, void *userdata,
|
|
void (*callback)(void *, const LuaVariableSymbol *expr))
|
|
{
|
|
LuaSymbol *symbol;
|
|
FOR_EACH_PTR(statement->symbols, LuaSymbol, symbol)
|
|
{
|
|
assert(symbol->symbol_type == SYM_LOCAL);
|
|
callback(userdata, &symbol->variable);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
void raviX_for_statement_foreach_expression(const ForStatement *statement, void *userdata,
|
|
void (*callback)(void *, const Expression *expr))
|
|
{
|
|
AstNode *node;
|
|
FOR_EACH_PTR(statement->expr_list, AstNode, node)
|
|
{
|
|
assert(node->type >= EXPR_LITERAL && node->type <= EXPR_FUNCTION_CALL);
|
|
callback(userdata, (Expression *)node);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
const Scope *raviX_for_statement_body_scope(const ForStatement *statement)
|
|
{
|
|
return statement->for_body;
|
|
}
|
|
void raviX_for_statement_body_foreach_statement(const ForStatement *statement, void *userdata,
|
|
void (*callback)(void *userdata, const Statement *statement))
|
|
{
|
|
AstNode *node;
|
|
FOR_EACH_PTR(statement->for_statement_list, AstNode, node)
|
|
{
|
|
assert(node->type <= STMT_EXPR);
|
|
callback(userdata, (Statement *)node);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
const VariableType *raviX_literal_expression_type(const LiteralExpression *expression)
|
|
{
|
|
return &expression->type;
|
|
}
|
|
const SemInfo *raviX_literal_expression_literal(const LiteralExpression *expression) { return &expression->u; }
|
|
const VariableType *raviX_symbol_expression_type(const SymbolExpression *expression)
|
|
{
|
|
return &expression->type;
|
|
}
|
|
const LuaSymbol *raviX_symbol_expression_symbol(const SymbolExpression *expression)
|
|
{
|
|
return expression->var;
|
|
}
|
|
const VariableType *raviX_index_expression_type(const IndexExpression *expression)
|
|
{
|
|
return &expression->type;
|
|
}
|
|
const Expression *raviX_index_expression_expression(const IndexExpression *expression)
|
|
{
|
|
assert(expression->expr->type >= EXPR_LITERAL && expression->expr->type <= EXPR_FUNCTION_CALL);
|
|
return (const Expression *)expression->expr;
|
|
}
|
|
const VariableType *raviX_unary_expression_type(const UnaryExpression *expression)
|
|
{
|
|
return &expression->type;
|
|
}
|
|
const Expression *raviX_unary_expression_expression(const UnaryExpression *expression)
|
|
{
|
|
assert(expression->expr->type >= EXPR_LITERAL && expression->expr->type <= EXPR_FUNCTION_CALL);
|
|
return (const Expression *)expression->expr;
|
|
}
|
|
UnaryOperatorType raviX_unary_expression_operator(const UnaryExpression *expression)
|
|
{
|
|
return expression->unary_op;
|
|
}
|
|
const VariableType *raviX_binary_expression_type(const BinaryExpression *expression)
|
|
{
|
|
return &expression->type;
|
|
}
|
|
const Expression *raviX_binary_expression_left_expression(const BinaryExpression *expression)
|
|
{
|
|
assert(expression->expr_left->type >= EXPR_LITERAL && expression->expr_left->type <= EXPR_FUNCTION_CALL);
|
|
return (const Expression *)expression->expr_left;
|
|
}
|
|
const Expression *raviX_binary_expression_right_expression(const BinaryExpression *expression)
|
|
{
|
|
assert(expression->expr_right->type >= EXPR_LITERAL && expression->expr_right->type <= EXPR_FUNCTION_CALL);
|
|
return (const Expression *)expression->expr_right;
|
|
}
|
|
BinaryOperatorType raviX_binary_expression_operator(const BinaryExpression *expression)
|
|
{
|
|
return expression->binary_op;
|
|
}
|
|
const VariableType *
|
|
raviX_table_element_assignment_expression_type(const TableElementAssignmentExpression *expression)
|
|
{
|
|
return &expression->type;
|
|
}
|
|
const Expression *
|
|
raviX_table_element_assignment_expression_key(const TableElementAssignmentExpression *expression)
|
|
{
|
|
if (!expression->key_expr)
|
|
return NULL;
|
|
assert(expression->key_expr->type >= EXPR_LITERAL && expression->key_expr->type <= EXPR_FUNCTION_CALL);
|
|
return (const Expression *)expression->key_expr;
|
|
}
|
|
const Expression *
|
|
raviX_table_element_assignment_expression_value(const TableElementAssignmentExpression *expression)
|
|
{
|
|
assert(expression->value_expr->type >= EXPR_LITERAL && expression->value_expr->type <= EXPR_FUNCTION_CALL);
|
|
return (const Expression *)expression->value_expr;
|
|
}
|
|
const VariableType *raviX_table_literal_expression_type(const TableLiteralExpression *expression)
|
|
{
|
|
return &expression->type;
|
|
}
|
|
void raviX_table_literal_expression_foreach_element(
|
|
const TableLiteralExpression *expression, void *userdata,
|
|
void (*callback)(void *, const TableElementAssignmentExpression *expr))
|
|
{
|
|
AstNode *node;
|
|
FOR_EACH_PTR(expression->expr_list, AstNode, node)
|
|
{
|
|
assert(node->type == EXPR_TABLE_ELEMENT_ASSIGN);
|
|
callback(userdata, &node->table_elem_assign_expr);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
|
|
const VariableType *raviX_suffixed_expression_type(const SuffixedExpression *expression)
|
|
{
|
|
return &expression->type;
|
|
}
|
|
const Expression *raviX_suffixed_expression_primary(const SuffixedExpression *expression)
|
|
{
|
|
assert(expression->primary_expr->type >= EXPR_LITERAL && expression->primary_expr->type <= EXPR_FUNCTION_CALL);
|
|
return (const Expression *)expression->primary_expr;
|
|
}
|
|
void raviX_suffixed_expression_foreach_suffix(const SuffixedExpression *expression, void *userdata,
|
|
void (*callback)(void *, const Expression *expr))
|
|
{
|
|
AstNode *node;
|
|
FOR_EACH_PTR(expression->suffix_list, AstNode, node)
|
|
{
|
|
assert(node->type >= EXPR_LITERAL && node->type <= EXPR_FUNCTION_CALL);
|
|
callback(userdata, (Expression *)node);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
|
|
const VariableType *raviX_function_call_expression_type(const FunctionCallExpression *expression)
|
|
{
|
|
return &expression->type;
|
|
}
|
|
// Can return NULL
|
|
const StringObject *
|
|
raviX_function_call_expression_method_name(const FunctionCallExpression *expression)
|
|
{
|
|
return expression->method_name;
|
|
}
|
|
void raviX_function_call_expression_foreach_argument(const FunctionCallExpression *expression, void *userdata,
|
|
void (*callback)(void *, const Expression *expr))
|
|
{
|
|
AstNode *node;
|
|
FOR_EACH_PTR(expression->arg_list, AstNode, node)
|
|
{
|
|
assert(node->type >= EXPR_LITERAL && node->type <= EXPR_FUNCTION_CALL);
|
|
callback(userdata, (Expression *)node);
|
|
}
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
const FunctionExpression *raviX_scope_owning_function(const Scope *scope)
|
|
{
|
|
assert(scope->function->type == EXPR_FUNCTION);
|
|
return &scope->function->function_expr;
|
|
}
|
|
RAVICOMP_EXPORT const Scope *raviX_scope_parent_scope(const Scope *scope)
|
|
{
|
|
return scope->parent;
|
|
}
|
|
RAVICOMP_EXPORT void raviX_scope_foreach_symbol(const Scope *scope, void *userdata,
|
|
void (*callback)(void *userdata, const LuaSymbol *symbol))
|
|
{
|
|
LuaSymbol *symbol;
|
|
FOR_EACH_PTR(scope->symbol_list, LuaSymbol, symbol) { callback(userdata, symbol); }
|
|
END_FOR_EACH_PTR(node)
|
|
}
|
|
enum SymbolType raviX_symbol_type(const LuaSymbol *symbol) { return symbol->symbol_type; }
|
|
const LuaVariableSymbol *raviX_symbol_variable(const LuaSymbol *symbol)
|
|
{
|
|
assert(symbol->symbol_type == SYM_GLOBAL || symbol->symbol_type == SYM_LOCAL);
|
|
return &symbol->variable;
|
|
}
|
|
const LuaUpvalueSymbol *raviX_symbol_upvalue(const LuaSymbol *symbol)
|
|
{
|
|
assert(symbol->symbol_type == SYM_UPVALUE);
|
|
return &symbol->upvalue;
|
|
}
|
|
const LuaLabelSymbol *raviX_symbol_label(const LuaSymbol *symbol)
|
|
{
|
|
assert(symbol->symbol_type == SYM_LABEL);
|
|
return &symbol->label;
|
|
}
|
|
const StringObject *raviX_label_name(const LuaLabelSymbol *symbol) { return symbol->label_name; }
|
|
const Scope *raviX_label_scope(const LuaLabelSymbol *symbol) { return symbol->block; }
|
|
const VariableType *raviX_upvalue_symbol_type(const LuaUpvalueSymbol *symbol)
|
|
{
|
|
return &symbol->value_type;
|
|
}
|
|
const LuaVariableSymbol *raviX_upvalue_target_variable(const LuaUpvalueSymbol *symbol)
|
|
{
|
|
if (symbol->target_variable->symbol_type == SYM_ENV) {
|
|
assert(symbol->target_function == NULL);
|
|
return NULL;
|
|
}
|
|
assert(symbol->target_variable->symbol_type == SYM_LOCAL);
|
|
return &symbol->target_variable->variable;
|
|
}
|
|
const FunctionExpression *raviX_upvalue_target_function(const LuaUpvalueSymbol *symbol)
|
|
{
|
|
if (symbol->target_variable->symbol_type == SYM_ENV) {
|
|
assert(symbol->target_function == NULL);
|
|
return NULL;
|
|
}
|
|
assert(symbol->target_function->type == EXPR_FUNCTION);
|
|
return &symbol->target_function->function_expr;
|
|
}
|
|
unsigned raviX_upvalue_index(const LuaUpvalueSymbol *symbol) { return symbol->upvalue_index; }
|