parser
Dibyendu Majumdar 4 years ago
parent 5ce1cc3c64
commit f1a310df95

@ -209,7 +209,7 @@ struct ast_node {
const TString *s;
} u;
} literal_expr;
struct {
struct { /* primaryexp -> NAME | '(' expr ')', NAME is parsed as AST_SYMBOL_EXPR */
struct var_type type;
struct lua_symbol *var;
} symbol_expr;
@ -246,10 +246,10 @@ struct ast_node {
expression */
struct ast_node *value_expr;
} indexed_assign_expr; /* Assign values in table constructor */
struct {
struct { /* constructor -> '{' [ field { sep field } [sep] ] '}' where sep -> ',' | ';' */
struct var_type type;
struct ast_node_list *expr_list;
} table_expr; /* table constructor expression */
} table_expr; /* table constructor expression AST_TABLE_EXPR occurs in function call and simple expr */
struct {
/* suffixedexp -> primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
/* suffix_list may have AST_FIELD_SELECTOR_EXPR, AST_Y_INDEX_EXPR, AST_FUNCTION_CALL_EXPR */
@ -338,7 +338,7 @@ enum opcode {
op_bxor,
op_bxorii,
op_shl,
opshlii,
op_shlii,
op_shr,
op_shrii,
op_eq,
@ -368,10 +368,11 @@ enum opcode {
op_totype,
op_not,
op_bnot,
op_loadglobal,
};
enum pseudo_type {
PSEUDO_LOCAL,
PSEUDO_SYMBOL,
PSEUDO_TEMP_FLT,
PSEUDO_TEMP_INT,
PSEUDO_TEMP_ANY,
@ -386,7 +387,7 @@ enum pseudo_type {
struct pseudo {
unsigned type : 4, regnum : 16;
union {
struct lua_symbol *symbol; /* PSEUDO_LOCAL */
struct lua_symbol *symbol; /* PSEUDO_SYMBOL */
const struct constant *constant; /* PSEUDO_CONSTANT */
ravitype_t temp_type; /* PSEUDO_TEMP* */
struct proc *proc; /* PSEUDO_PROC */

@ -10,7 +10,7 @@ Copyright (C) 2018-2020 Dibyendu Majumdar
#include <stdlib.h>
#include <stddef.h>
static struct pseudo *linearize_expr(struct proc *proc, struct ast_node *expr);
static struct pseudo *linearize_expression(struct proc *proc, struct ast_node *expr);
static inline unsigned alloc_reg(struct pseudo_generator *generator) {
if (generator->free_pos > 0) {
@ -122,14 +122,15 @@ static const struct constant *allocate_string_constant(struct proc *proc, const
return add_constant(proc, &c);
}
struct pseudo *allocate_local_pseudo(struct proc *proc, struct lua_symbol *sym, unsigned reg) {
assert(sym->symbol_type == SYM_LOCAL);
struct pseudo *allocate_symbol_pseudo(struct proc *proc, struct lua_symbol *sym, unsigned reg) {
assert(sym->var.pseudo == NULL);
struct pseudo *pseudo = dmrC_allocator_allocate(&proc->linearizer->pseudo_allocator, 0);
pseudo->type = PSEUDO_LOCAL;
pseudo->type = PSEUDO_SYMBOL;
pseudo->symbol = sym;
pseudo->regnum = reg;
sym->var.pseudo = pseudo;
if (sym->symbol_type == SYM_LOCAL) {
sym->var.pseudo = pseudo;
}
return pseudo;
}
@ -294,7 +295,7 @@ static struct pseudo *linearize_literal(struct proc *proc, struct ast_node *expr
static struct pseudo *linearize_unaryop(struct proc *proc, struct ast_node *node) {
UnOpr op = node->unary_expr.unary_op;
struct pseudo *subexpr = linearize_expr(proc, node->unary_expr.expr);
struct pseudo *subexpr = linearize_expression(proc, node->unary_expr.expr);
ravitype_t subexpr_type = node->unary_expr.expr->common_expr.type.type_code;
enum opcode targetop = op_nop;
switch (op) {
@ -367,8 +368,8 @@ static struct pseudo *linearize_binaryop(struct proc *proc, struct ast_node *nod
BinOpr op = node->binary_expr.binary_op;
struct ast_node *e1 = node->binary_expr.expr_left;
struct ast_node *e2 = node->binary_expr.expr_right;
struct pseudo *operand1 = linearize_expr(proc, e1);
struct pseudo *operand2 = linearize_expr(proc, e2);
struct pseudo *operand1 = linearize_expression(proc, e1);
struct pseudo *operand2 = linearize_expression(proc, e2);
enum opcode targetop;
switch (op) {
@ -524,32 +525,52 @@ static struct pseudo *linearize_function_expr(struct proc *proc, struct ast_node
return target;
}
static struct pseudo *linearize_symbol_expression(struct proc *proc, struct ast_node *expr) {
struct lua_symbol *sym = expr->symbol_expr.var;
if (sym->symbol_type == SYM_GLOBAL) {
struct pseudo *target = allocate_temp_pseudo(proc, RAVI_TANY);
struct pseudo *operand = allocate_symbol_pseudo(proc, sym, 0); // no register actually
struct instruction *insn = alloc_instruction(proc, op_loadglobal);
ptrlist_add((struct ptr_list **)&insn->operands, operand, &proc->linearizer->ptrlist_allocator);
ptrlist_add((struct ptr_list **)&insn->targets, target, &proc->linearizer->ptrlist_allocator);
ptrlist_add((struct ptr_list **)&proc->current_bb->insns, insn, &proc->linearizer->ptrlist_allocator);
return target;
}
else if (sym->symbol_type == SYM_LOCAL) {
return sym->var.pseudo;
}
else {
abort();
return NULL;
}
}
/*
* Suffixed expression examples:
* f()[1]
* x[1][2]
* x.y[1]
*/
static struct pseudo * linearize_suffixedexpr(struct proc* proc, struct ast_node* node) {
/* suffixedexp -> primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
struct pseudo *prev_psedo = linearize_expr(proc, node->suffixed_expr.primary_expr);
struct ast_node* prev_node = node->suffixed_expr.primary_expr;
struct ast_node* this_node;
FOR_EACH_PTR(node->suffixed_expr.suffix_list, this_node) {
if (this_node->type == AST_Y_INDEX_EXPR) {
}
else if (this_node->type == AST_FIELD_SELECTOR_EXPR) {
}
else if (this_node->type == AST_FUNCTION_CALL_EXPR) {
}
prev_node = this_node;
static struct pseudo *linearize_suffixedexpr(struct proc *proc, struct ast_node *node) {
/* suffixedexp -> primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
struct pseudo *prev_psedo = linearize_expression(proc, node->suffixed_expr.primary_expr);
struct ast_node *prev_node = node->suffixed_expr.primary_expr;
struct ast_node *this_node;
FOR_EACH_PTR(node->suffixed_expr.suffix_list, this_node) {
if (this_node->type == AST_Y_INDEX_EXPR) {
}
else if (this_node->type == AST_FIELD_SELECTOR_EXPR) {
}
END_FOR_EACH_PTR(node);
//copy_type(node->suffixed_expr.type, prev_node->common_expr.type);
else if (this_node->type == AST_FUNCTION_CALL_EXPR) {
}
prev_node = this_node;
}
END_FOR_EACH_PTR(node);
// copy_type(node->suffixed_expr.type, prev_node->common_expr.type);
return prev_psedo;
}
static struct pseudo *linearize_expr(struct proc *proc, struct ast_node *expr) {
static struct pseudo *linearize_expression(struct proc *proc, struct ast_node *expr) {
switch (expr->type) {
case AST_LITERAL_EXPR: {
return linearize_literal(proc, expr);
@ -563,6 +584,12 @@ static struct pseudo *linearize_expr(struct proc *proc, struct ast_node *expr) {
case AST_UNARY_EXPR: {
return linearize_unaryop(proc, expr);
} break;
case AST_SUFFIXED_EXPR: {
return linearize_suffixedexpr(proc, expr);
} break;
case AST_SYMBOL_EXPR: {
return linearize_symbol_expression(proc, expr);
} break;
default:
abort();
break;
@ -575,7 +602,7 @@ static void linearize_expr_list(struct proc *proc, struct ast_node_list *expr_li
struct pseudo_list **pseudo_list) {
struct ast_node *expr;
FOR_EACH_PTR(expr_list, expr) {
struct pseudo *pseudo = linearize_expr(proc, expr);
struct pseudo *pseudo = linearize_expression(proc, expr);
ptrlist_add((struct ptr_list **)pseudo_list, pseudo, &proc->linearizer->ptrlist_allocator);
}
END_FOR_EACH_PTR(expr);
@ -746,7 +773,7 @@ static void start_scope(struct linearizer *linearizer, struct proc *proc, struct
FOR_EACH_PTR(scope->symbol_list, sym) {
if (sym->symbol_type == SYM_LOCAL) {
uint8_t reg = alloc_reg(&proc->local_pseudos);
allocate_local_pseudo(proc, sym, reg);
allocate_symbol_pseudo(proc, sym, reg);
printf("Assigning register %d to local %s\n", (int)reg, getstr(sym->var.var_name));
}
}
@ -764,7 +791,7 @@ static void end_scope(struct linearizer *linearizer, struct proc *proc) {
FOR_EACH_PTR_REVERSE(scope->symbol_list, sym) {
if (sym->symbol_type == SYM_LOCAL) {
struct pseudo *pseudo = sym->var.pseudo;
assert(pseudo && pseudo->type == PSEUDO_LOCAL && pseudo->symbol == sym);
assert(pseudo && pseudo->type == PSEUDO_SYMBOL && pseudo->symbol == sym);
printf("Free register %d for local %s\n", (int)pseudo->regnum, getstr(sym->var.var_name));
free_reg(&proc->local_pseudos, pseudo->regnum);
}
@ -821,17 +848,29 @@ void output_pseudo(struct pseudo *pseudo, membuff_t *mb) {
case PSEUDO_TRUE:
membuff_add_string(mb, "true");
break;
case PSEUDO_SYMBOL: {
switch (pseudo->symbol->symbol_type) {
case SYM_UPVALUE:
case SYM_LOCAL:
case SYM_GLOBAL: {
membuff_add_string(mb, getstr(pseudo->symbol->var.var_name));
break;
}
default:
assert(0);
}
} break;
}
}
static const char *op_codenames[] = {
"NOOP", "RET", "LOADK", "LOADNIL", "LOADBOOL", "ADD", "ADDff", "ADDfi", "ADDii",
"SUB", "SUBff", "SUBfi", "SUBif", "SUBii", "MUL", "MULff", "MULfi", "MULii",
"DIV", "DIVff", "DIVfi", "DIVif", "DIVii", "IDIV", "BAND", "BANDii", "BOR",
"BORii", "BXOR", "BXORii", "SHL", "SHLii", "SHR", "SHRii", "EQ", "EQii",
"EQff", "LT", "LIii", "LTff", "LE", "LEii", "LEff", "MOD", "POW",
"CLOSURE", "UNM", "UNMi", "UNMf", "LEN", "LENi", "TOINT", "TOFLT", "TOCLOSURE",
"TOSTRING", "TOIARRAY", "TOFARRAY", "TOTABLE", "TOTYPE", "NOT", "BNOT"};
"NOOP", "RET", "LOADK", "LOADNIL", "LOADBOOL", "ADD", "ADDff", "ADDfi", "ADDii",
"SUB", "SUBff", "SUBfi", "SUBif", "SUBii", "MUL", "MULff", "MULfi", "MULii",
"DIV", "DIVff", "DIVfi", "DIVif", "DIVii", "IDIV", "BAND", "BANDii", "BOR",
"BORii", "BXOR", "BXORii", "SHL", "SHLii", "SHR", "SHRii", "EQ", "EQii",
"EQff", "LT", "LIii", "LTff", "LE", "LEii", "LEff", "MOD", "POW",
"CLOSURE", "UNM", "UNMi", "UNMf", "LEN", "LENi", "TOINT", "TOFLT", "TOCLOSURE",
"TOSTRING", "TOIARRAY", "TOFARRAY", "TOTABLE", "TOTYPE", "NOT", "BNOT", "LOADGLOBAL"};
void output_pseudo_list(struct pseudo_list *list, membuff_t *mb) {
struct pseudo *pseudo;

Loading…
Cancel
Save