hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

expr.ha (12905B)


      1 // License: MPL-2.0
      2 // (c) 2021 Drew DeVault <sir@cmpwn.com>
      3 // (c) 2021 Ember Sawady <ecs@d2evs.net>
      4 // (c) 2022 Sebastian <sebastian@sebsite.pw>
      5 use hare::lex;
      6 
      7 // An identifier access expression.
      8 //
      9 // 	foo
     10 export type access_identifier = ident;
     11 
     12 // An index access expression.
     13 //
     14 // 	foo[0]
     15 export type access_index = struct {
     16 	object: *expr,
     17 	index: *expr,
     18 };
     19 
     20 // A struct field access expression.
     21 //
     22 // 	foo.bar
     23 export type access_field = struct {
     24 	object: *expr,
     25 	field: str,
     26 };
     27 
     28 // A tuple field access expression.
     29 //
     30 // 	foo.1
     31 export type access_tuple = struct {
     32 	object: *expr,
     33 	value: *expr,
     34 };
     35 
     36 // An access expression.
     37 export type access_expr = (access_identifier | access_index | access_field
     38 	| access_tuple);
     39 
     40 // An align expression.
     41 //
     42 // 	align(int)
     43 export type align_expr = *_type;
     44 
     45 // The form of an allocation expression.
     46 //
     47 // 	alloc(foo)    // OBJECT
     48 // 	alloc(foo...) // COPY
     49 export type alloc_form = enum {
     50 	OBJECT,
     51 	COPY,
     52 };
     53 
     54 // An allocation expression.
     55 //
     56 // 	alloc(foo)
     57 // 	alloc(foo...)
     58 // 	alloc(foo, bar)
     59 export type alloc_expr = struct {
     60 	init: *expr,
     61 	form: alloc_form,
     62 	capacity: nullable *expr,
     63 };
     64 
     65 // An append expression.
     66 //
     67 // 	append(foo, bar, (more), baz...)
     68 export type append_expr = struct {
     69 	object: *expr,
     70 	variadic: nullable *expr,
     71 	values: []*expr,
     72 	is_static: bool,
     73 };
     74 
     75 // An assertion expression.
     76 //
     77 // 	assert(foo)
     78 // 	assert(foo, "error")
     79 // 	abort()
     80 // 	abort("error")
     81 export type assert_expr = struct {
     82 	cond: nullable *expr,
     83 	message: nullable *expr,
     84 	is_static: bool,
     85 };
     86 
     87 // An assignment expression.
     88 //
     89 // 	foo = bar
     90 export type assign_expr = struct {
     91 	op: (binarithm_op | void),
     92 	object: *expr,
     93 	value: *expr,
     94 	indirect: bool,
     95 };
     96 
     97 // A binary arithmetic operator
     98 export type binarithm_op = enum {
     99 	// TODO: Rehome this with the checked AST?
    100 
    101 	BAND,	// &
    102 	BOR,	// |
    103 	DIV,	// /
    104 	GT,	// >
    105 	GTEQ,	// >=
    106 	LAND,	// &&
    107 	LEQUAL,	// ==
    108 	LESS,	// <
    109 	LESSEQ,	// <=
    110 	LOR,	// ||
    111 	LSHIFT,	// <<
    112 	LXOR,	// ^^
    113 	MINUS,	// -
    114 	MODULO,	// %
    115 	NEQUAL,	// !=
    116 	PLUS,	// +
    117 	RSHIFT,	// >>
    118 	TIMES,	// *
    119 	BXOR,	// ^
    120 };
    121 
    122 // A binary arithmetic expression.
    123 //
    124 // 	foo * bar
    125 export type binarithm_expr = struct {
    126 	op: binarithm_op,
    127 	lvalue: *expr,
    128 	rvalue: *expr,
    129 };
    130 
    131 // A single variable biding.
    132 //
    133 // 	foo: int = bar
    134 // 	(foo, foo2): int = bar
    135 export type binding = struct {
    136 	name: (str | binding_unpack),
    137 	_type: nullable *_type,
    138 	init: *expr,
    139 };
    140 
    141 // Tuple unpacking binding.
    142 //
    143 // 	(foo, _, bar)
    144 export type binding_unpack = [](str | void);
    145 
    146 // A variable binding expression.
    147 //
    148 // 	let foo: int = bar, ...
    149 export type binding_expr = struct {
    150 	is_static: bool,
    151 	is_const: bool,
    152 	bindings: []binding,
    153 };
    154 
    155 // A break expression. The label is set to empty string if absent.
    156 //
    157 // 	break :label
    158 export type break_expr = label;
    159 
    160 // A function call expression.
    161 //
    162 // 	foo(bar)
    163 export type call_expr = struct {
    164 	lvalue: *expr,
    165 	variadic: bool,
    166 	args: []*expr,
    167 };
    168 
    169 // The kind of cast expression being used.
    170 export type cast_kind = enum {
    171 	// TODO: Should this be rehomed with the checked AST?
    172 
    173 	CAST,
    174 	ASSERTION,
    175 	TEST,
    176 };
    177 
    178 // A cast expression.
    179 //
    180 // 	foo: int
    181 // 	foo as int
    182 // 	foo is int
    183 export type cast_expr = struct {
    184 	kind: cast_kind,
    185 	value: *expr,
    186 	_type: *_type,
    187 };
    188 
    189 // A compound expression.
    190 //
    191 // 	{
    192 // 		foo;
    193 // 		bar;
    194 // 		// ...
    195 // 	}
    196 export type compound_expr = struct {
    197 	exprs: []*expr,
    198 	label: label,
    199 };
    200 
    201 // An array constant.
    202 //
    203 // 	[foo, bar, ...]
    204 export type array_constant = struct {
    205 	expand: bool,
    206 	values: []*expr,
    207 };
    208 
    209 // A single struct field and value.
    210 //
    211 // 	foo: int = 10
    212 export type struct_value = struct {
    213 	name: str,
    214 	_type: nullable *_type,
    215 	init: *expr,
    216 };
    217 
    218 // A struct constant.
    219 //
    220 // 	struct { foo: int = bar, struct { baz = quux }, ... }
    221 export type struct_constant = struct {
    222 	autofill: bool,
    223 	alias: ident, // [] for anonymous
    224 	fields: [](struct_value | *struct_constant),
    225 };
    226 
    227 // A tuple constant.
    228 //
    229 // 	(foo, bar, ...)
    230 export type tuple_constant = []*expr;
    231 
    232 // The value "null".
    233 export type _null = void;
    234 
    235 // A scalar value.
    236 export type value = (bool | _null | str | rune | void);
    237 
    238 // An integer or float constant.
    239 export type number_constant = struct {
    240 	suff: lex::ltok,
    241 	value: (i64 | u64 | f64),
    242 	sign: bool, // true if negative, false otherwise
    243 };
    244 
    245 // A constant expression.
    246 export type constant_expr = (value | array_constant | number_constant |
    247 	struct_constant | tuple_constant);
    248 
    249 // A continue expression. The label is set to empty string if absent.
    250 //
    251 // 	continue :label
    252 export type continue_expr = label;
    253 
    254 // A deferred expression.
    255 //
    256 // 	defer foo
    257 export type defer_expr = *expr;
    258 
    259 // A delete expression.
    260 //
    261 // 	delete(foo[10])
    262 // 	delete(foo[4..42])
    263 export type delete_expr = struct {
    264 	object: *expr,
    265 	is_static: bool,
    266 };
    267 
    268 // A for loop.
    269 //
    270 // 	for (let foo = 0; foo < bar; baz) quux
    271 export type for_expr = struct {
    272 	bindings: nullable *expr,
    273 	cond: *expr,
    274 	afterthought: nullable *expr,
    275 	body: *expr,
    276 };
    277 
    278 // A free expression.
    279 //
    280 // 	free(foo)
    281 export type free_expr = *expr;
    282 
    283 // An if or if..else expression.
    284 //
    285 // 	if (foo) bar else baz
    286 export type if_expr = struct {
    287 	cond: *expr,
    288 	tbranch: *expr,
    289 	fbranch: nullable *expr,
    290 };
    291 
    292 // An insert expression.
    293 //
    294 // 	insert(foo[0], bar, (more), baz...)
    295 export type insert_expr = struct {
    296 	object: *expr,
    297 	variadic: nullable *expr,
    298 	values: []*expr,
    299 	is_static: bool,
    300 };
    301 
    302 // :label. The ":" character is not included.
    303 export type label = str;
    304 
    305 // A length expression.
    306 //
    307 // 	len(foo)
    308 export type len_expr = *expr;
    309 
    310 // A match case.
    311 //
    312 //	case type => exprs
    313 //	case let name: type => exprs
    314 export type match_case = struct {
    315 	name: str,
    316 	_type: nullable *_type,
    317 	exprs: []*expr,
    318 };
    319 
    320 // A match expression.
    321 //
    322 // 	match (foo) { case int => bar; ... }
    323 export type match_expr = struct {
    324 	value: *expr,
    325 	cases: []match_case,
    326 	default: []*expr,
    327 };
    328 
    329 // An offset expression.
    330 //
    331 // 	offset(foo.bar)
    332 export type offset_expr = *expr;
    333 
    334 // An error propagation expression.
    335 //
    336 // 	foo?
    337 export type propagate_expr = *expr;
    338 
    339 // An error assertion expression.
    340 //
    341 // 	foo!
    342 export type error_assert_expr = *expr;
    343 
    344 // A return statement.
    345 //
    346 // 	return foo
    347 export type return_expr = nullable *expr;
    348 
    349 // A size expression.
    350 //
    351 // 	size(int)
    352 export type size_expr = *_type;
    353 
    354 // A slicing expression.
    355 //
    356 // 	foo[bar..baz]
    357 export type slice_expr = struct {
    358 	object: *expr,
    359 	start: nullable *expr,
    360 	end: nullable *expr,
    361 };
    362 
    363 // A switch case.
    364 //
    365 // 	case value => exprs
    366 export type switch_case = struct {
    367 	options: []*expr, // [] for default case
    368 	exprs: []*expr,
    369 };
    370 
    371 // A switch expression.
    372 //
    373 // 	switch (foo) { case bar => baz; ... }
    374 export type switch_expr = struct {
    375 	value: *expr,
    376 	cases: []switch_case,
    377 };
    378 
    379 // A unary operator
    380 export type unarithm_op = enum {
    381 	// TODO: Should this be rehomed with the checked AST?
    382 
    383 	ADDR,	// &
    384 	BNOT,	// ~
    385 	DEREF,	// *
    386 	LNOT,	// !
    387 	MINUS,	// -
    388 };
    389 
    390 // A unary arithmetic expression.
    391 //
    392 // 	!example
    393 export type unarithm_expr = struct {
    394 	op: unarithm_op,
    395 	operand: *expr,
    396 };
    397 
    398 // A vastart expression.
    399 //
    400 // 	vastart()
    401 export type vastart_expr = void;
    402 
    403 // A vaarg expression.
    404 //
    405 // 	vaarg(ap)
    406 export type vaarg_expr = *expr;
    407 
    408 // A vaend expression.
    409 //
    410 // 	vaend(ap)
    411 export type vaend_expr = *expr;
    412 
    413 // A C-style variadic expression.
    414 export type variadic_expr = (vastart_expr | vaarg_expr | vaend_expr);
    415 
    416 // A yield expression.
    417 //
    418 // 	yield foo
    419 export type yield_expr = struct {
    420 	label: label,
    421 	value: nullable *expr,
    422 };
    423 
    424 // A Hare expression.
    425 export type expr = struct {
    426 	start: lex::location,
    427 	end: lex::location,
    428 	expr: (access_expr | align_expr | alloc_expr | append_expr |
    429 		assert_expr | assign_expr | binarithm_expr | binding_expr |
    430 		break_expr | call_expr | cast_expr | constant_expr |
    431 		continue_expr | defer_expr | delete_expr | for_expr |
    432 		free_expr | error_assert_expr | if_expr | insert_expr |
    433 		compound_expr | match_expr | len_expr | size_expr |
    434 		offset_expr | propagate_expr | return_expr | slice_expr |
    435 		switch_expr | unarithm_expr | variadic_expr | yield_expr),
    436 };
    437 
    438 // Frees resources associated with a Hare [[expr]]ession.
    439 export fn expr_finish(e: (expr | nullable *expr)) void = match (e) {
    440 case let e: nullable *expr =>
    441 	match (e) {
    442 	case null => void;
    443 	case let e: *expr =>
    444 		expr_finish(*e);
    445 		free(e);
    446 	};
    447 case let e: expr =>
    448 	match (e.expr) {
    449 	case let a: access_expr =>
    450 		match (a) {
    451 		case let i: access_identifier =>
    452 			ident_free(i);
    453 		case let i: access_index =>
    454 			expr_finish(i.object);
    455 			expr_finish(i.index);
    456 		case let f: access_field =>
    457 			expr_finish(f.object);
    458 			free(f.field);
    459 		case let t: access_tuple =>
    460 			expr_finish(t.object);
    461 			expr_finish(t.value);
    462 		};
    463 	case let a: align_expr =>
    464 		type_finish(a: *_type);
    465 	case let a: alloc_expr =>
    466 		expr_finish(a.init);
    467 		expr_finish(a.capacity);
    468 	case let a: append_expr =>
    469 		expr_finish(a.object);
    470 		match (a.variadic) {
    471 		case null => void;
    472 		case let v: *expr =>
    473 			expr_finish(v);
    474 		};
    475 		for (let i = 0z; i < len(a.values); i += 1) {
    476 			expr_finish(a.values[i]);
    477 		};
    478 		free(a.values);
    479 	case let a: assert_expr =>
    480 		expr_finish(a.cond);
    481 		expr_finish(a.message);
    482 	case let a: assign_expr =>
    483 		expr_finish(a.object);
    484 		expr_finish(a.value);
    485 	case let b: binarithm_expr =>
    486 		expr_finish(b.lvalue);
    487 		expr_finish(b.rvalue);
    488 	case let b: binding_expr =>
    489 		for (let i = 0z; i < len(b.bindings); i += 1) {
    490 			match (b.bindings[i].name) {
    491 			case let s: str =>
    492 				free(s);
    493 			case let u: binding_unpack =>
    494 				for (let i = 0z; i < len(u); i += 1) {
    495 					match (u[i]) {
    496 					case let s: str =>
    497 						free(s);
    498 					case => void;
    499 					};
    500 				};
    501 				free(u);
    502 			};
    503 			type_finish(b.bindings[i]._type);
    504 			expr_finish(b.bindings[i].init);
    505 		};
    506 		free(b.bindings);
    507 	case let b: break_expr =>
    508 		free(b);
    509 	case let c: call_expr =>
    510 		expr_finish(c.lvalue);
    511 		for (let i = 0z; i < len(c.args); i += 1) {
    512 			expr_finish(c.args[i]);
    513 		};
    514 		free(c.args);
    515 	case let c: cast_expr =>
    516 		expr_finish(c.value);
    517 		type_finish(c._type);
    518 	case let c: compound_expr =>
    519 		for (let i = 0z; i < len(c.exprs); i += 1) {
    520 			expr_finish(c.exprs[i]);
    521 		};
    522 		free(c.exprs);
    523 		free(c.label);
    524 	case let c: constant_expr =>
    525 		match (c) {
    526 		case let a: array_constant =>
    527 			for (let i = 0z; i < len(a.values); i += 1) {
    528 				expr_finish(a.values[i]);
    529 			};
    530 			free(a.values);
    531 		case let s: struct_constant =>
    532 			struct_constant_finish(s);
    533 		case let t: tuple_constant =>
    534 			for (let i = 0z; i < len(t); i += 1) {
    535 				expr_finish(t[i]);
    536 			};
    537 			free(t);
    538 		case (value | number_constant) => void;
    539 		};
    540 	case let c: continue_expr =>
    541 		free(c);
    542 	case let d: defer_expr =>
    543 		expr_finish(d: *expr);
    544 	case let d: delete_expr =>
    545 		expr_finish(d.object);
    546 	case let e: error_assert_expr =>
    547 		expr_finish(e);
    548 	case let f: for_expr =>
    549 		expr_finish(f.bindings);
    550 		expr_finish(f.cond);
    551 		expr_finish(f.afterthought);
    552 		expr_finish(f.body);
    553 	case let f: free_expr =>
    554 		expr_finish(f: *expr);
    555 	case let i: if_expr =>
    556 		expr_finish(i.cond);
    557 		expr_finish(i.tbranch);
    558 		expr_finish(i.fbranch);
    559 	case let e: insert_expr =>
    560 		expr_finish(e.object);
    561 		match (e.variadic) {
    562 		case null => void;
    563 		case let v: *expr =>
    564 			expr_finish(v);
    565 		};
    566 		for (let i = 0z; i < len(e.values); i += 1) {
    567 			expr_finish(e.values[i]);
    568 		};
    569 		free(e.values);
    570 	case let l: len_expr =>
    571 		expr_finish(l: *expr);
    572 	case let m: match_expr =>
    573 		expr_finish(m.value);
    574 		for (let i = 0z; i < len(m.cases); i += 1) {
    575 			free(m.cases[i].name);
    576 			type_finish(m.cases[i]._type);
    577 			const exprs = m.cases[i].exprs;
    578 			for (let i = 0z; i < len(exprs); i += 1) {
    579 				expr_finish(exprs[i]);
    580 			};
    581 			free(exprs);
    582 		};
    583 		free(m.cases);
    584 		for (let i = 0z; i < len(m.default); i += 1) {
    585 			expr_finish(m.default[i]);
    586 		};
    587 		free(m.default);
    588 	case let o: offset_expr =>
    589 		expr_finish(o: *expr);
    590 	case let p: propagate_expr =>
    591 		expr_finish(p);
    592 	case let r: return_expr =>
    593 		expr_finish(r: *expr);
    594 	case let s: size_expr =>
    595 		type_finish(s: *_type);
    596 	case let s: slice_expr =>
    597 		expr_finish(s.object);
    598 		expr_finish(s.start);
    599 		expr_finish(s.end);
    600 	case let s: switch_expr =>
    601 		expr_finish(s.value);
    602 		for (let i = 0z; i < len(s.cases); i += 1) {
    603 			let opts = s.cases[i].options;
    604 			for (let j = 0z; j < len(opts); j += 1) {
    605 				expr_finish(opts[j]);
    606 			};
    607 			free(opts);
    608 
    609 			let exprs = s.cases[i].exprs;
    610 			for (let j = 0z; j < len(exprs); j += 1) {
    611 				expr_finish(exprs[j]);
    612 			};
    613 			free(exprs);
    614 		};
    615 		free(s.cases);
    616 	case let u: unarithm_expr =>
    617 		expr_finish(u.operand);
    618 	case let v: variadic_expr =>
    619 		match (v) {
    620 		case vastart_expr => void;
    621 		case let v: vaarg_expr =>
    622 			expr_finish(v);
    623 		case let v: vaend_expr =>
    624 			expr_finish(v);
    625 		};
    626 	case let y: yield_expr =>
    627 		free(y.label);
    628 		expr_finish(y.value);
    629 	};
    630 };
    631 
    632 fn struct_constant_finish(s: struct_constant) void = {
    633 	ident_free(s.alias);
    634 	for (let i = 0z; i < len(s.fields); i += 1) {
    635 		match (s.fields[i]) {
    636 		case let v: struct_value =>
    637 			free(v.name);
    638 			type_finish(v._type);
    639 			expr_finish(v.init);
    640 		case let c: *struct_constant =>
    641 			struct_constant_finish(*c);
    642 			free(c);
    643 		};
    644 	};
    645 	free(s.fields);
    646 };