ox

The Ox programming language, compiler and tools (WIP)
Log | Files | Refs | README | LICENSE

ast.c (3191B)


      1 #include "../parser.h"
      2 #include "../utils.h"
      3 
      4 #include <stdio.h>
      5 #include <string.h>
      6 #include <stdbool.h>
      7 #include <assert.h>
      8 
      9 Node*
     10 make_postfix_node(UnaryOp op, Node* operand)
     11 {
     12 	Node* node = (Node*)calloc(1, sizeof(Node));
     13 	if (node == NULL) panic("make_postfix_node: could not alloc");
     14 	node->type = NODE_UNARY_EXPR;
     15 	node->scope = NULL;
     16 	node->next = NULL;
     17 	node->data.unary_expr.op = op;
     18 	node->data.unary_expr.operand = operand;
     19 	node->data.unary_expr.is_postfix = true;
     20 	return node;
     21 }
     22 
     23 Node*
     24 make_subscript_node(Node* array, Node* index)
     25 {
     26 	Node* node = calloc(1, sizeof(Node));
     27 	if (node == NULL) panic("make_subscript_node: could not alloc");
     28 	node->type = NODE_SUBSCRIPT_EXPR;
     29 	node->scope = NULL;
     30 	node->next = NULL;
     31 	node->data.subscript_expr.array = array;
     32 	node->data.subscript_expr.index = index;
     33 	return node;
     34 }
     35 
     36 Node*
     37 make_number_node(Parser* par)
     38 {
     39 	Token tok = consume(par);
     40 	assert(tok.type == TOKEN_INT_LITERAL || tok.type == TOKEN_FLOAT_LITERAL);
     41 	size_t len = tok.end - tok.start;
     42 	char buf[len + 1]; // strtod needs a \0 terminated string
     43 	for (size_t i = 0; i < len; i++)
     44 		buf[i] = par->src[tok.start + i];
     45 	buf[len] = '\0';
     46 	double value = strtod(buf, NULL);
     47 	Node* node = (Node*)calloc(1, sizeof(Node));
     48 	if (node == NULL) panic("make_number_node: could not alloc");
     49 	node->type = tok.type == TOKEN_INT_LITERAL ? NODE_INT_LITERAL : NODE_FLOAT_LITERAL;
     50 	node->scope = NULL;
     51 	node->data.number.value = value;
     52 	return node;
     53 }
     54 
     55 Node*
     56 make_unary_node(UnaryOp op, Node* operand)
     57 {
     58 	Node* node = (Node*)calloc(1, sizeof(Node));
     59 	if (node == NULL) panic("make_unary_node: could not alloc");
     60 	node->type = NODE_UNARY_EXPR;
     61 	node->scope = NULL;
     62 	node->next = NULL;
     63 	node->data.unary_expr.op = op;
     64 	node->data.unary_expr.operand = operand;
     65 	node->data.unary_expr.is_postfix = false;
     66 	return node;
     67 }
     68 
     69 Node*
     70 make_string_node(Parser* par)
     71 {
     72 	Token tok = consume(par);
     73 	Node* node = (Node*)calloc(1, sizeof(Node));
     74 	if (node == NULL) panic("make_string_node: could not alloc");
     75 	node->type = NODE_STRING_LITERAL;
     76 	node->scope = NULL;
     77 	node->data.string.value.start = (tok.start + 1); // "...
     78 	node->data.string.value.end = (tok.end - 1);     // ..."
     79 	return node;
     80 }
     81 
     82 Node*
     83 make_binary_node(OpType op, Node* lhs, Node* rhs)
     84 {
     85 	Node* node = (Node*)calloc(1, sizeof(Node));
     86 	if (node == NULL) panic("make_binary_node: could not alloc");
     87 	node->type = NODE_BINARY_EXPR;
     88 	node->scope = NULL;
     89 	node->next = NULL;
     90 	node->data.binary_expr.op = op;
     91 	node->data.binary_expr.lhs = lhs;
     92 	node->data.binary_expr.rhs = rhs;
     93 	return node;
     94 }
     95 
     96 Node*
     97 make_empty_statement(void)
     98 {
     99 	Node* node = (Node*)calloc(1, sizeof(Node));
    100 	if (node == NULL) panic("make_empty_statement: could not alloc");
    101 	assert(node != NULL);
    102 	node->type = NODE_EMPTY_STATEMENT;
    103 	node->scope = NULL;
    104 	return node;
    105 }
    106 
    107 Node*
    108 make_call_node(Node* callee, NodeVec args)
    109 {
    110 	Node* call = (Node*)calloc(1, sizeof(Node));
    111 	if (call == NULL) panic("make_call_node: could not alloc");
    112 	assert(call != NULL);
    113 	call->type = NODE_CALL_EXPR;
    114 	call->scope = NULL;
    115 	call->data.call_expr.callee = callee;
    116 	call->data.call_expr.args = args.items;
    117 	call->data.call_expr.cap = args.cap;
    118 	call->data.call_expr.len = args.len;
    119 	return call;
    120 }