ast.c (3475B)
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_boolean_node(Parser* par, bool truthy) 71 { 72 consume(par); 73 Node* node = (Node*)calloc(1, sizeof(Node)); 74 if (node == NULL) panic("make_boolean_node: could not alloc"); 75 node->type = NODE_BOOL_LITERAL; 76 node->scope = NULL; 77 node->data.boolean.value = truthy; 78 return node; 79 } 80 81 Node* 82 make_string_node(Parser* par) 83 { 84 Token tok = consume(par); 85 Node* node = (Node*)calloc(1, sizeof(Node)); 86 if (node == NULL) panic("make_string_node: could not alloc"); 87 node->type = NODE_STRING_LITERAL; 88 node->scope = NULL; 89 node->data.string.value.start = (tok.start + 1); // "... 90 node->data.string.value.end = (tok.end - 1); // ..." 91 return node; 92 } 93 94 Node* 95 make_binary_node(OpType op, Node* lhs, Node* rhs) 96 { 97 Node* node = (Node*)calloc(1, sizeof(Node)); 98 if (node == NULL) panic("make_binary_node: could not alloc"); 99 node->type = NODE_BINARY_EXPR; 100 node->scope = NULL; 101 node->next = NULL; 102 node->data.binary_expr.op = op; 103 node->data.binary_expr.lhs = lhs; 104 node->data.binary_expr.rhs = rhs; 105 return node; 106 } 107 108 Node* 109 make_empty_statement(void) 110 { 111 Node* node = (Node*)calloc(1, sizeof(Node)); 112 if (node == NULL) panic("make_empty_statement: could not alloc"); 113 assert(node != NULL); 114 node->type = NODE_EMPTY_STATEMENT; 115 node->scope = NULL; 116 return node; 117 } 118 119 Node* 120 make_call_node(Node* callee, NodeVec args) 121 { 122 Node* call = (Node*)calloc(1, sizeof(Node)); 123 if (call == NULL) panic("make_call_node: could not alloc"); 124 assert(call != NULL); 125 call->type = NODE_CALL_EXPR; 126 call->scope = NULL; 127 call->data.call_expr.callee = callee; 128 call->data.call_expr.args = args.items; 129 call->data.call_expr.cap = args.cap; 130 call->data.call_expr.len = args.len; 131 return call; 132 }