Files
WL/src/assemble.c
T
2025-08-02 21:46:07 +02:00

242 lines
5.1 KiB
C

#include "parse.h"
#include "assemble.h"
#define MAX_SCOPES 32
typedef enum {
SCOPE_FUNC,
SCOPE_FOR,
SCOPE_WHILE,
SCOPE_IF,
SCOPE_ELSE,
} ScopeType;
typedef struct {
ScopeType type;
// TODO
} Scope;
typedef struct {
int depth;
Scope scopes[MAX_SCOPES];
} Assembler;
int count_nodes(Node *head)
{
int n = 0;
Node *node = head;
while (node) {
n++;
node = node->next;
}
return n;
}
void assemble_node(Node *node)
{
switch (node->type) {
case NODE_FUNC_DECL:
{
append_u8 (out, OPCODE_JUMP);
append_u64(out, xxx);
int arg_count = count_nodes(node->func_args);
Node *preallocated[32];
Node *args = preallocated;
if (arg_count > COUNT(preallocated)) {
args = malloc(arg_count * sizeof(Node*));
if (args == NULL) {
// TODO
}
}
for (int i = arg_count-1; i >= 0; i--) {
append_u8 (out, OPCODE_ASS);
append_u64(out, xxx);
}
if (is_expr(node->func_body)) {
assemble_node(node->func_body);
append_u8(out, OPCODE_RET);
} else
assemble_node(node->func_body);
append_u8(out, OPCODE_NOPE);
if (args != preallocated)
free(args);
}
break;
case NODE_FUNC_CALL:
{
Node *func = node->left;
Node *args = node->right;
int arg_count = 0;
Node *arg = args;
while (arg) {
assemble_node(arg);
arg_count++;
arg = arg->next;
}
assemble_node(arg);
append_u8(OPCODE_CALL);
append_u32(arg_count);
if (func->type == NODE_VALUE_VAR) {
// TODO
}
}
break;
case NODE_BLOCK:
{
Node *stmt = node->child;
while (stmt) {
assemble_node(stmt);
if (is_expr(stmt))
append_u8(out, OPCODE_POP);
stmt = stmt->next;
}
}
break;
case NODE_IFELSE:
{
assemble_node(node->cond);
append_u8 (out, OPCODE_JIFP);
append_u32(out, xxx);
assemble_node(node->left);
if (node->right)
assemble_node(node->right);
}
break;
case NODE_FOR:
{
assemble_node(node->for_set);
// TODO
}
break;
case NODE_WHILE:
break;
case NODE_SELECT:
break;
case NODE_OPER_POS:
assemble_node(node->left);
break;
case NODE_OPER_NEG:
assemble_node(node->left);
append(out, OPCODE_NEG);
break;
case NODE_OPER_ASS:
break;
case NODE_OPER_EQL:
assemble_node(node->left);
assemble_node(node->right);
append(out, OPCODE_EQL);
break;
case NODE_OPER_NQL:
assemble_node(node->left);
assemble_node(node->right);
append(out, OPCODE_NQL);
break;
case NODE_OPER_LSS:
assemble_node(node->left);
assemble_node(node->right);
append(out, OPCODE_LSS);
break;
case NODE_OPER_GRT:
assemble_node(node->left);
assemble_node(node->right);
append(out, OPCODE_GRT);
break;
case NODE_OPER_ADD:
assemble_node(node->left);
assemble_node(node->right);
append(out, OPCODE_ADD);
break;
case NODE_OPER_SUB:
assemble_node(node->left);
assemble_node(node->right);
append(out, OPCODE_SUB);
break;
case NODE_OPER_MUL:
assemble_node(node->left);
assemble_node(node->right);
append(out, OPCODE_MUL);
break;
case NODE_OPER_DIV:
assemble_node(node->left);
assemble_node(node->right);
append(out, OPCODE_DIV);
break;
case NODE_OPER_MOD:
assemble_node(node->left);
assemble_node(node->right);
append(out, OPCODE_MOD);
break;
case NODE_VALUE_INT:
append_u8 (out, OPCODE_PUSHI);
append_u64(out, node->ival);
break;
case NODE_VALUE_FLOAT:
append_u8 (out, OPCODE_PUSHF);
append_f64(out, node->fval);
break;
case NODE_VALUE_STR:
append_u8 (out, OPCODE_PUSHS);
append_u64(out, xxx);
break;
case NODE_VALUE_VAR:
append_u8 (out, OPCODE_PUSHV);
append_u64(out, node->ival);
break;
case NODE_VALUE_HTML:
TODO;
break;
case NODE_VALUE_ARRAY:
append_u8 (out, OPCODE_PUSHA);
append_u64(out, xxx);
break;
case NODE_VALUE_MAP:
append_u8 (out, OPCODE_PUSHM);
append_u64(out, xxx);
break;
}
}
AssembleResult assemble(Node *root)
{
assemble_node(root);
}