hare

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

expr.ha (12657B)


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