ast.c (3475B)
#include "../parser.h"
#include "../utils.h"
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>
Node*
make_postfix_node(UnaryOp op, Node* operand)
{
Node* node = (Node*)calloc(1, sizeof(Node));
if (node == NULL) panic("make_postfix_node: could not alloc");
node->type = NODE_UNARY_EXPR;
node->scope = NULL;
node->next = NULL;
node->data.unary_expr.op = op;
node->data.unary_expr.operand = operand;
node->data.unary_expr.is_postfix = true;
return node;
}
Node*
make_subscript_node(Node* array, Node* index)
{
Node* node = calloc(1, sizeof(Node));
if (node == NULL) panic("make_subscript_node: could not alloc");
node->type = NODE_SUBSCRIPT_EXPR;
node->scope = NULL;
node->next = NULL;
node->data.subscript_expr.array = array;
node->data.subscript_expr.index = index;
return node;
}
Node*
make_number_node(Parser* par)
{
Token tok = consume(par);
assert(tok.type == TOKEN_INT_LITERAL || tok.type == TOKEN_FLOAT_LITERAL);
size_t len = tok.end - tok.start;
char buf[len + 1]; // strtod needs a \0 terminated string
for (size_t i = 0; i < len; i++)
buf[i] = par->src[tok.start + i];
buf[len] = '\0';
double value = strtod(buf, NULL);
Node* node = (Node*)calloc(1, sizeof(Node));
if (node == NULL) panic("make_number_node: could not alloc");
node->type = tok.type == TOKEN_INT_LITERAL ? NODE_INT_LITERAL : NODE_FLOAT_LITERAL;
node->scope = NULL;
node->data.number.value = value;
return node;
}
Node*
make_unary_node(UnaryOp op, Node* operand)
{
Node* node = (Node*)calloc(1, sizeof(Node));
if (node == NULL) panic("make_unary_node: could not alloc");
node->type = NODE_UNARY_EXPR;
node->scope = NULL;
node->next = NULL;
node->data.unary_expr.op = op;
node->data.unary_expr.operand = operand;
node->data.unary_expr.is_postfix = false;
return node;
}
Node*
make_boolean_node(Parser* par, bool truthy)
{
consume(par);
Node* node = (Node*)calloc(1, sizeof(Node));
if (node == NULL) panic("make_boolean_node: could not alloc");
node->type = NODE_BOOL_LITERAL;
node->scope = NULL;
node->data.boolean.value = truthy;
return node;
}
Node*
make_string_node(Parser* par)
{
Token tok = consume(par);
Node* node = (Node*)calloc(1, sizeof(Node));
if (node == NULL) panic("make_string_node: could not alloc");
node->type = NODE_STRING_LITERAL;
node->scope = NULL;
node->data.string.value.start = (tok.start + 1); // "...
node->data.string.value.end = (tok.end - 1); // ..."
return node;
}
Node*
make_binary_node(OpType op, Node* lhs, Node* rhs)
{
Node* node = (Node*)calloc(1, sizeof(Node));
if (node == NULL) panic("make_binary_node: could not alloc");
node->type = NODE_BINARY_EXPR;
node->scope = NULL;
node->next = NULL;
node->data.binary_expr.op = op;
node->data.binary_expr.lhs = lhs;
node->data.binary_expr.rhs = rhs;
return node;
}
Node*
make_empty_statement(void)
{
Node* node = (Node*)calloc(1, sizeof(Node));
if (node == NULL) panic("make_empty_statement: could not alloc");
assert(node != NULL);
node->type = NODE_EMPTY_STATEMENT;
node->scope = NULL;
return node;
}
Node*
make_call_node(Node* callee, NodeVec args)
{
Node* call = (Node*)calloc(1, sizeof(Node));
if (call == NULL) panic("make_call_node: could not alloc");
assert(call != NULL);
call->type = NODE_CALL_EXPR;
call->scope = NULL;
call->data.call_expr.callee = callee;
call->data.call_expr.args = args.items;
call->data.call_expr.cap = args.cap;
call->data.call_expr.len = args.len;
return call;
}