libpulsar
A modular compiler for the pulsar programming language
Loading...
Searching...
No Matches
ast.c
Go to the documentation of this file.
1// Copyright (C) 2023 Ethan Uppal. All rights reserved.
2
3#include "ast.h"
4
5#include <stdio.h> // printf
6#include "util/arena.h" // astalloc
7
8struct ps_node* ps_node_let_new(struct ps_token* name, bool is_mutable,
9 struct ps_type* type, struct ps_expr* value) {
10 struct ps_node* node = astalloc(sizeof(*node));
11 node->type = PS_NODE_LET;
12
13 struct ps_node_let* let = &node->value.let;
14 let->name = name;
16 let->type = type;
17 let->value = value;
18
19 return node;
20}
21
22struct ps_node* ps_node_fn_new(struct ps_token* name, struct ps_type* ret_type,
23 struct ps_type_field_arr* params, enum ps_fn_qualifiers qualifiers,
24 struct ps_node_block* body) {
25 struct ps_node* node = astalloc(sizeof(*node));
26 node->type = PS_NODE_FN;
27
28 struct ps_node_fn* fn = &node->value.fn;
29 fn->name = name;
30 fn->ret_type = ret_type;
31 fn->params = params;
33 fn->body = body;
34
35 return node;
36}
37
38PS_PRINT_IMPL(ps_name, {
39 for (usize i = 0; i < self->length; i++) {
40 if (i > 0) {
41 printf("::");
42 }
43 ps_token_print(&self->contents[i], 0);
44 }
45})
46
47struct ps_node* ps_node_import_new(struct ps_name* name) {
48 struct ps_node* node = astalloc(sizeof(*node));
49 node->type = PS_NODE_IMPORT;
50
51 struct ps_node_import* import = &node->value.import;
52 import->name = name;
53
54 return node;
55}
56
57struct ps_node* ps_node_extern_new(struct ps_token* name,
58 struct ps_type_tuple* sig) {
59 struct ps_node* node = astalloc(sizeof(*node));
60 node->type = PS_NODE_EXTERN;
61
62 struct ps_node_extern* extern_ = &node->value.extern_;
63 extern_->name = name;
64 extern_->sig = sig;
65
66 return node;
67}
68
69struct ps_node* ps_node_expr_stm_new(struct ps_expr* expr) {
70 struct ps_node* node = astalloc(sizeof(*node));
71 node->type = PS_NODE_EXPR_STM;
72
73 struct ps_node_expr_stm* expr_stm = &node->value.expr_stm;
74 expr_stm->expr = expr;
75
76 return node;
77}
78
79struct ps_node* ps_node_block_stm_new(struct ps_node_block* block) {
80 struct ps_node* node = astalloc(sizeof(*node));
81 node->type = PS_NODE_BLOCK;
82
83 node->value.block = block;
84
85 return node;
86}
87
89 struct ps_node_fn_arr* methods) {
90 struct ps_node* node = astalloc(sizeof(*node));
91 node->type = PS_NODE_STRUCT;
92
93 struct ps_node_struct* struct_ = &node->value.struct_;
94 struct_->type = type;
95 struct_->methods = methods;
96
97 return node;
98}
99
101 struct ps_node_fn_arr* methods) {
102 struct ps_node* node = astalloc(sizeof(*node));
103 node->type = PS_NODE_ENUM;
104
105 struct ps_node_enum* enum_ = &node->value.enum_;
106 enum_->type = type;
107 enum_->methods = methods;
108
109 return node;
110}
111
112struct ps_node* ps_node_for_new(struct ps_node_let* init, struct ps_expr* cond,
113 struct ps_node_expr_stm* step, struct ps_node_block* body) {
114 struct ps_node* node = astalloc(sizeof(*node));
115 node->type = PS_NODE_FOR;
116
117 struct ps_node_for* for_ = &node->value.for_;
118 for_->init = init;
119 for_->cond = cond;
120 for_->step = step;
121 for_->body = body;
122
123 return node;
124}
125
126struct ps_node* ps_node_while_new(struct ps_expr* cond,
127 struct ps_node_block* body) {
128 struct ps_node* node = astalloc(sizeof(*node));
129 node->type = PS_NODE_WHILE;
130
131 struct ps_node_while* while_ = &node->value.while_;
132 while_->cond = cond;
133 while_->body = body;
134
135 return node;
136}
137
138struct ps_node* ps_node_if_new(struct ps_expr* cond, struct ps_node_block* body,
139 struct ps_node_block* else_body) {
140 struct ps_node* node = astalloc(sizeof(*node));
141 node->type = PS_NODE_IF;
142
143 struct ps_node_if* if_ = &node->value.if_;
144 if_->cond = cond;
145 if_->body = body;
146 if_->else_body = else_body;
147
148 return node;
149}
150
152 struct ps_node* node = astalloc(sizeof(*node));
153 node->type = PS_NODE_RETURN;
154
155 struct ps_node_return* return_ = &node->value.return_;
156 return_->value = value;
157
158 return node;
159}
160
163 printf("let %s%s", self->is_mutable ? "mut " : "", self->name->start);
164 if (self->type) {
165 printf(": ");
166 ps_type_print(self->type, 0);
167 }
168 printf(" = ");
169 ps_expr_print(self->value, 0);
170})
171
174 if (self->qualifiers & PS_FN_PUBLIC) {
175 printf("public ");
176 }
177 if (self->qualifiers & PS_FN_PRIVATE) {
178 printf("private ");
179 }
180 if (self->qualifiers & PS_FN_STATIC) {
181 printf("static ");
182 }
183 if (self->qualifiers & PS_FN_INLINE) {
184 printf("inline ");
185 }
186 printf("fn %s", self->name->start);
187 ps_type_field_arr_print(self->params, 0);
188 if (self->ret_type) {
189 printf(" -> ");
190 ps_type_print(self->ret_type, 0);
191 }
192 printf(" ");
193 ps_node_block_print(self->body, 0, indent);
194})
195
198 printf("import ");
199 for (usize i = 0; i < self->name->length; i++) {
200 if (i) printf("::");
201 printf("%s", $arr(self->name)[i]->start);
202 }
203})
204
207 printf("extern %s", self->name->start);
208 ps_type_tuple_print(self->sig, 0);
209})
210
213 ps_expr_print(self->expr, 0);
214})
215
216PS_IPRINT_IMPL(ps_node_block, {
217 printf("{\n");
218 for (size_t i = 0; i < self->length; i++) {
219 ps_node_print(self->contents[i], '\n', ps_next_indent());
220 }
222 printf("}");
223})
224
227 ps_type_struct_print(self->type, 0, ps_next_indent());
228})
229
232 ps_type_enum_print(self->type, 0, ps_next_indent());
233})
234
237 // printf("for ");
238 // ps_node_let_print(self->init, 0, 0);
239 // printf("; ");
240 // ps_expr_print(self->cond, 0);
241 // printf("; ");
242 // ps_node_expr_stm_print(self->step, 0, 0);
243 // printf(" ");
244 // ps_node_block_print(self->body, 0, indent);
245})
246
249 printf("while ");
250 ps_expr_print(self->cond, 0);
251 printf(" ");
252 ps_node_block_print(self->body, 0, indent);
253})
254
257 printf("if ");
258 ps_expr_print(self->cond, 0);
259 printf(" ");
260 ps_node_block_print(self->body, 0, indent);
261 if (self->else_body) {
262 printf(" else ");
263 ps_node_block_print(self->else_body, 0, indent);
264 }
265})
266
269 printf("return");
270 if (self->value) {
271 printf(" ");
272 ps_expr_print(self->value, 0);
273 }
274})
275
277 switch (self->type) {
278 case PS_NODE_LET:
279 ps_node_let_print(&self->value.let, 0, indent);
280 break;
281 case PS_NODE_FN:
282 ps_node_fn_print(&self->value.fn, 0, indent);
283 break;
284 case PS_NODE_IMPORT:
285 ps_node_import_print(&self->value.import, 0, indent);
286 break;
287 case PS_NODE_EXTERN:
288 ps_node_extern_print(&self->value.extern_, 0, indent);
289 break;
290 case PS_NODE_EXPR_STM:
291 ps_node_expr_stm_print(&self->value.expr_stm, 0, indent);
292 break;
293 case PS_NODE_BLOCK:
295 ps_node_block_print(self->value.block, 0, indent);
296 break;
297 case PS_NODE_STRUCT:
298 ps_node_struct_print(&self->value.struct_, 0, indent);
299 break;
300 case PS_NODE_ENUM:
301 ps_node_enum_print(&self->value.enum_, 0, indent);
302 break;
303 case PS_NODE_FOR:
304 ps_node_for_print(&self->value.for_, 0, indent);
305 break;
306 case PS_NODE_WHILE:
307 ps_node_while_print(&self->value.while_, 0, indent);
308 break;
309 case PS_NODE_IF:
310 ps_node_if_print(&self->value.if_, 0, indent);
311 break;
312 case PS_NODE_RETURN:
313 ps_node_return_print(&self->value.return_, 0, indent);
314 break;
315 case PS_NODE_TRAIT:
316 PS_NO_IMPL();
317 case PS_NODE_EXPR:
318 ps_abort("idk what this is");
319 default:
320 ps_abort("you're missing a case here");
321 }
322})
323
324struct ps_expr* ps_expr_id_new(struct ps_token* name) {
325 struct ps_expr* expr = astalloc(sizeof(*expr));
326 expr->expr_type = PS_EXPR_ID_EXPR;
327 expr->type = NULL;
328
329 struct ps_expr_id* id = &expr->value.id_expr;
330 id->name = name;
331
332 return expr;
333}
334
336 struct ps_expr* expr = astalloc(sizeof(*expr));
337 expr->expr_type = PS_EXPR_LIT_EXPR;
338 expr->type = NULL;
339
340 struct ps_expr_lit* lit = &expr->value.lit_expr;
341 lit->type = PS_EXPR_LIT_U64;
342 lit->value.uint_val = value;
343 lit->token = token;
344
345 return expr;
346}
347
349 struct ps_expr* expr = astalloc(sizeof(*expr));
350 expr->expr_type = PS_EXPR_LIT_EXPR;
351 expr->type = NULL;
352
353 struct ps_expr_lit* lit = &expr->value.lit_expr;
354 lit->type = PS_EXPR_LIT_I64;
355 lit->value.int_val = value;
356 lit->token = token;
357
358 return expr;
359}
360
362 struct ps_expr* expr = astalloc(sizeof(*expr));
363 expr->expr_type = PS_EXPR_LIT_EXPR;
364 expr->type = NULL;
365
366 struct ps_expr_lit* lit = &expr->value.lit_expr;
367 lit->type = PS_EXPR_LIT_F64;
368 lit->value.float_val = value;
369 lit->token = token;
370
371 return expr;
372}
373
374struct ps_expr* ps_expr_lit_new_bool(bool value, struct ps_token* token) {
375 struct ps_expr* expr = astalloc(sizeof(*expr));
376 expr->expr_type = PS_EXPR_LIT_EXPR;
377 expr->type = NULL;
378
379 struct ps_expr_lit* lit = &expr->value.lit_expr;
380 lit->type = PS_EXPR_LIT_BOOL;
381 lit->value.bool_val = value;
382 lit->token = token;
383
384 return expr;
385}
386
388 struct ps_expr* expr = astalloc(sizeof(*expr));
389 expr->expr_type = PS_EXPR_LIT_EXPR;
390 expr->type = NULL;
391
392 struct ps_expr_lit* lit = &expr->value.lit_expr;
393 lit->type = PS_EXPR_LIT_STR;
394 lit->value.str_val = value;
395 lit->token = token;
396
397 return expr;
398}
399
400struct ps_expr* ps_expr_lit_new_interp_str(struct ps_interp_str* value) {
401 struct ps_expr* expr = astalloc(sizeof(*expr));
402 expr->expr_type = PS_EXPR_LIT_EXPR;
403 expr->type = NULL;
404
405 struct ps_expr_lit* lit = &expr->value.lit_expr;
406 lit->type = PS_EXPR_LIT_INTERP_STR;
408 lit->token = NULL; // not sure if good idea
409
410 return expr;
411}
412
413struct ps_expr* ps_expr_lit_new_unit(struct ps_token* token) {
414 struct ps_expr* expr = astalloc(sizeof(*expr));
415 expr->expr_type = PS_EXPR_LIT_EXPR;
416 expr->type = NULL;
417
418 struct ps_expr_lit* lit = &expr->value.lit_expr;
419 lit->type = PS_EXPR_LIT_UNIT;
420 lit->token = token;
421
422 return expr;
423}
424
425struct ps_expr* ps_expr_binary_new(struct ps_expr* lhs, struct ps_token* op,
426 struct ps_expr* rhs) {
427 struct ps_expr* expr = astalloc(sizeof(*expr));
428 expr->expr_type = PS_EXPR_BIN_EXPR;
429 expr->type = NULL;
430
431 struct ps_expr_binary* binary = &expr->value.bin_expr;
432 binary->op = op;
433 binary->lhs = lhs;
434 binary->rhs = rhs;
435
436 return expr;
437}
438
439struct ps_expr* ps_expr_unary_new(struct ps_token* op, struct ps_expr* rhs) {
440 struct ps_expr* expr = astalloc(sizeof(*expr));
441 expr->expr_type = PS_EXPR_UN_EXPR;
442 expr->type = NULL;
443
444 struct ps_expr_unary* unary = &expr->value.un_expr;
445 unary->op = op;
446 unary->rhs = rhs;
447
448 return expr;
449}
450
451struct ps_expr* ps_expr_call_new(struct ps_token* callee,
452 struct ps_expr_arr* args) {
453 struct ps_expr* expr = astalloc(sizeof(*expr));
454 expr->expr_type = PS_EXPR_CALL_EXPR;
455 expr->type = NULL;
456
457 struct ps_expr_call* call = &expr->value.call_expr;
458 call->callee = callee;
459 call->args = args;
460
461 return expr;
462}
463
464PS_PRINT_IMPL(ps_interp_str, {
465 putchar('"');
466 for (usize i = 0; i < self->length; i++) {
467 struct ps_expr* part = self->contents[i];
468 if (part->expr_type == PS_EXPR_LIT_EXPR
469 && part->value.lit_expr.type == PS_EXPR_LIT_STR) {
470 printf("%s", part->value.lit_expr.value.str_val);
471 } else {
472 printf("\\(");
473 ps_expr_print(part, ')');
474 }
475 }
476 putchar('"');
477})
478
480 switch (self->type) {
481 case PS_EXPR_LIT_U64:
482 printf("%llu", self->value.uint_val);
483 break;
484 case PS_EXPR_LIT_I64:
485 printf("%lld", self->value.int_val);
486 break;
487 case PS_EXPR_LIT_F64:
488 printf("%f", self->value.float_val);
489 break;
490 case PS_EXPR_LIT_BOOL:
491 printf("%s", self->value.bool_val ? "true" : "false");
492 break;
493 case PS_EXPR_LIT_STR:
494 printf("\"%s\"", self->value.str_val);
495 break;
496 case PS_EXPR_LIT_INTERP_STR:
497 ps_interp_str_print(self->value.interp_str_val, 0);
498 break;
499 case PS_EXPR_LIT_UNIT:
500 printf("()");
501 break;
502 }
503})
504
505PS_PRINT_IMPL(ps_expr_id, { printf("%s", self->name->start); })
506
508 putchar('(');
509 ps_expr_print(self->lhs, 0);
510 printf(" %s ", self->op->start);
511 ps_expr_print(self->rhs, 0);
512 putchar(')');
513})
514
516 printf("%s ", self->op->start);
517 ps_expr_print(self->rhs, 0);
518})
519
521 printf("%s(", self->callee->start);
522 for (usize i = 0; i < self->args->length; i++) {
523 if (i > 0) {
524 printf(", ");
525 }
526 ps_expr_print(self->args->contents[i], 0);
527 }
528 putchar(')');
529})
530
532 switch (self->expr_type) {
533 case PS_EXPR_ID_EXPR:
534 ps_expr_id_print(&self->value.id_expr, 0);
535 break;
536 case PS_EXPR_LIT_EXPR:
537 ps_expr_lit_print(&self->value.lit_expr, 0);
538 break;
539 case PS_EXPR_BIN_EXPR:
540 ps_expr_binary_print(&self->value.bin_expr, 0);
541 break;
542 case PS_EXPR_UN_EXPR:
543 ps_expr_unary_print(&self->value.un_expr, 0);
544 break;
545 case PS_EXPR_CALL_EXPR:
546 ps_expr_call_print(&self->value.call_expr, 0);
547 break;
548 }
549})
#define ps_abort(msg)
Aborts the program with the given message.
Definition abort.h:47
#define PS_NO_IMPL()
Aborts the program due to a function taking a path not yet implemented.
Definition abort.h:70
Defines an arena allocator for the compiler.
#define astalloc(n)
Definition arena.h:51
struct ps_expr * ps_expr_lit_new_f64(f64 value, struct ps_token *token)
Creates a new literal expression for a floating point number (of at most 64 bits).
Definition ast.c:361
struct ps_expr * ps_expr_unary_new(struct ps_token *op, struct ps_expr *rhs)
Creates a new unary expression.
Definition ast.c:439
struct ps_expr * ps_expr_lit_new_unit(struct ps_token *token)
Creates a new literal expression for a unit literal.
Definition ast.c:413
struct ps_expr * ps_expr_lit_new_u64(u64 value, struct ps_token *token)
Creates a new literal expression for an unsigned integer (of at most 64 bits).
Definition ast.c:335
struct ps_node * ps_node_return_new(struct ps_expr *value)
Creates a new return statement that returns the expression value.
Definition ast.c:151
struct ps_expr * ps_expr_lit_new_bool(bool value, struct ps_token *token)
Creates a new literal expression for a boolean.
Definition ast.c:374
struct ps_node * ps_node_struct_new(struct ps_type_struct *type, struct ps_node_fn_arr *methods)
Creates a new structure declaration.
Definition ast.c:88
struct ps_node * ps_node_extern_new(struct ps_token *name, struct ps_type_tuple *sig)
Definition ast.c:57
struct ps_node * ps_node_enum_new(struct ps_type_enum *type, struct ps_node_fn_arr *methods)
Creates a new enum declaration.
Definition ast.c:100
struct ps_node * ps_node_let_new(struct ps_token *name, bool is_mutable, struct ps_type *type, struct ps_expr *value)
Creates a new let statement initializing the variable name to the expression value.
Definition ast.c:8
struct ps_node * ps_node_expr_stm_new(struct ps_expr *expr)
Creates a new expression statement for expr.
Definition ast.c:69
struct ps_expr * ps_expr_lit_new_i64(i64 value, struct ps_token *token)
Creates a new literal expression for a signed integer (of at most 64 bits).
Definition ast.c:348
struct ps_expr * ps_expr_call_new(struct ps_token *callee, struct ps_expr_arr *args)
Creates a new call expression.
Definition ast.c:451
struct ps_expr * ps_expr_lit_new_str(STR value, struct ps_token *token)
Creates a new literal expression for a string.
Definition ast.c:387
struct ps_node * ps_node_fn_new(struct ps_token *name, struct ps_type *ret_type, struct ps_type_field_arr *params, enum ps_fn_qualifiers qualifiers, struct ps_node_block *body)
Creates a new function with the given name name, parameters params, and function body body.
Definition ast.c:22
struct ps_node * ps_node_for_new(struct ps_node_let *init, struct ps_expr *cond, struct ps_node_expr_stm *step, struct ps_node_block *body)
Creates a new for loop.
Definition ast.c:112
struct ps_node * ps_node_block_stm_new(struct ps_node_block *block)
Creates a new block statement.
Definition ast.c:79
struct ps_node * ps_node_if_new(struct ps_expr *cond, struct ps_node_block *body, struct ps_node_block *else_body)
Creates a new if statement on condition cond.
Definition ast.c:138
struct ps_expr * ps_expr_binary_new(struct ps_expr *lhs, struct ps_token *op, struct ps_expr *rhs)
Creates a new binary expression.
Definition ast.c:425
struct ps_node * ps_node_while_new(struct ps_expr *cond, struct ps_node_block *body)
Creates a new while loop.
Definition ast.c:126
struct ps_expr * ps_expr_lit_new_interp_str(struct ps_interp_str *value)
Creates a new literal expression for an interpolated string.
Definition ast.c:400
Abstract syntax tree.
struct ps_expr * ps_expr_id_new(struct ps_token *name)
Creates a new id expression.
struct ps_node * ps_node_import_new(struct ps_name *name)
Creates a new import statement.
ps_fn_qualifiers
Function qualifier flags.
Definition ast.h:52
@ PS_FN_INLINE
Inlined everywhere.
Definition ast.h:56
@ PS_FN_PUBLIC
Visible outside the module.
Definition ast.h:53
@ PS_FN_PRIVATE
Hidden outside the module.
Definition ast.h:54
@ PS_FN_STATIC
TODO:
Definition ast.h:55
#define f64
Definition def.h:52
#define STR
Definition def.h:40
#define u64
Definition def.h:48
#define i64
Definition def.h:47
#define usize
Definition def.h:50
#define PS_IPRINT_IMPL(T,...)
Definition print.h:20
#define ps_print_indent()
Definition print.h:27
#define ps_next_indent()
Definition print.h:28
#define PS_PRINT_IMPL(T,...)
Definition print.h:10
A binary operator.
Definition ast.h:162
struct ps_expr * rhs
Definition ast.h:165
struct ps_token * op
Definition ast.h:164
struct ps_expr * lhs
Definition ast.h:163
A function invocation.
Definition ast.h:175
struct ps_token * callee
Definition ast.h:178
struct ps_expr_arr * args
Definition ast.h:179
A variable name.
Definition ast.h:123
struct ps_token * name
Definition ast.h:124
An expression literal.
Definition ast.h:133
union ps_expr_lit::ps_expr_lit_value value
enum ps_expr_lit::ps_expr_lit_type type
struct ps_token * token
A token associated with the expression literal.
Definition ast.h:144
An unary operator.
Definition ast.h:169
struct ps_token * op
Definition ast.h:170
struct ps_expr * rhs
Definition ast.h:171
Expression nodes are represented with tagged unions.
Definition ast.h:187
enum ps_expr::ps_expr_type expr_type
struct ps_expr_lit lit_expr
Definition ast.h:195
struct ps_expr_binary bin_expr
Definition ast.h:196
union ps_expr::@1 value
struct ps_expr_call call_expr
Definition ast.h:198
struct ps_type * type
Definition ast.h:200
struct ps_expr_id id_expr
Definition ast.h:194
struct ps_expr_unary un_expr
Definition ast.h:197
struct ps_type_enum * type
Definition ast.h:96
struct ps_node_fn_arr * methods
Definition ast.h:97
struct ps_expr * expr
Definition ast.h:87
A reference to an external C function.
Definition ast.h:81
struct ps_type_tuple * sig
The type signature of the function.
Definition ast.h:83
struct ps_token * name
The name of the function.
Definition ast.h:82
struct ps_type * ret_type
Definition ast.h:62
struct ps_node_block * body
Definition ast.h:65
struct ps_type_field_arr * params
Definition ast.h:63
enum ps_fn_qualifiers qualifiers
Definition ast.h:64
struct ps_token * name
Definition ast.h:61
struct ps_node_expr_stm * step
Definition ast.h:103
struct ps_node_let * init
Definition ast.h:101
struct ps_node_block * body
Definition ast.h:104
struct ps_expr * cond
Definition ast.h:102
struct ps_expr * cond
Definition ast.h:113
struct ps_node_block * else_body
Definition ast.h:115
struct ps_node_block * body
Definition ast.h:114
struct ps_name * name
Definition ast.h:77
Parses "let `name`: `type` = `value`".
Definition ast.h:40
struct ps_token * name
Definition ast.h:41
bool is_mutable
Definition ast.h:42
struct ps_type * type
Definition ast.h:43
struct ps_expr * value
Definition ast.h:44
struct ps_expr * value
Definition ast.h:119
struct ps_node_fn_arr * methods
Definition ast.h:92
struct ps_type_struct * type
Definition ast.h:91
struct ps_node_block * body
Definition ast.h:109
struct ps_expr * cond
Definition ast.h:108
AST nodes are represented with tagged unions.
Definition ast.h:206
union ps_node::@2 value
struct ps_node_while while_
Definition ast.h:223
struct ps_node_extern extern_
Definition ast.h:216
struct ps_node_if if_
Definition ast.h:224
struct ps_node_enum enum_
Definition ast.h:221
struct ps_node_block * block
Definition ast.h:218
struct ps_node_struct struct_
Definition ast.h:220
struct ps_node_expr_stm expr_stm
Definition ast.h:217
struct ps_node_for for_
Definition ast.h:222
struct ps_node_return return_
Definition ast.h:225
struct ps_node_fn fn
Definition ast.h:214
struct ps_node_let let
Definition ast.h:213
enum ps_node::ps_node_type type
Represents a token.
Definition token.h:34
Definition type.h:66
struct ps_interp_str * interp_str_val
Definition ast.h:155