commit 552dcd235b500e6c7b33176e5d027ec9989f3bfe
parent dc4f509f414ae5c0d621ee56f3785b92fa630e0f
Author: Drew DeVault <sir@cmpwn.com>
Date: Thu, 2 Sep 2021 11:45:53 +0200
hare::*: simplify values
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
8 files changed, 30 insertions(+), 38 deletions(-)
diff --git a/cmd/harec/gen.ha b/cmd/harec/gen.ha
@@ -83,8 +83,8 @@ fn gen_expr_const(ctx: *context, expr: *unit::expr) value = {
const val: qval = match (constexpr) {
void => return vvoid,
b: bool => (if (b) 1u32 else 0u32): constant,
- unit::_null => 0u64, // XXX: Arch
- v: lex::value => abort(), // TODO
+ ast::_null => 0u64, // XXX: Arch
+ v: ast::value => abort(), // TODO
};
return value {
value = val,
diff --git a/hare/ast/expr.ha b/hare/ast/expr.ha
@@ -203,9 +203,11 @@ export type tuple_constant = []*expr;
// The value "null".
export type _null = void;
+// A scalar value.
+export type value = (void | bool | _null | ...lex::value);
+
// A constant expression.
-export type constant_expr = (void | bool | _null | lex::value | array_constant |
- struct_constant | tuple_constant);
+export type constant_expr = (value | array_constant | struct_constant | tuple_constant);
// A continue expression. The label is set to empty string if absent.
//
@@ -454,7 +456,7 @@ export fn expr_free(e: (expr | nullable *expr)) void = match (e) {
free(c.label);
},
c: constant_expr => match(c) {
- (void | lex::value) => void,
+ (void | _null | ...lex::value) => void,
a: array_constant => {
for (let i = 0z; i < len(a.values); i += 1) {
expr_free(a.values[i]);
diff --git a/hare/lex/token.ha b/hare/lex/token.ha
@@ -266,6 +266,9 @@ const bmap: [_]str = [
"*=",
];
+// The value "null".
+export type _null = void;
+
// A token value, used for tokens such as '1337' (an integer).
export type value = (str | rune | i64 | u64 | f64 | void);
diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha
@@ -437,7 +437,7 @@ fn cast(lexer: *lex::lexer, lvalue: (ast::expr | void)) (ast::expr | error) = {
fn constant(lexer: *lex::lexer) (ast::expr | error) = {
const tok = want(lexer)?;
- const expr = switch (tok.0) {
+ const expr: ast::value = switch (tok.0) {
ltok::LIT_U8, ltok::LIT_U16, ltok::LIT_U32, ltok::LIT_U64,
ltok::LIT_UINT, ltok::LIT_SIZE, ltok::LIT_I8, ltok::LIT_I16,
ltok::LIT_I32, ltok::LIT_I64, ltok::LIT_INT, ltok::LIT_ICONST,
@@ -909,9 +909,9 @@ fn postfix_dot(
void => {
let con = constant(lexer)?;
let val = con.expr as ast::constant_expr;
- synassert(lex::mkloc(lexer), val is lex::value,
+ synassert(lex::mkloc(lexer), val is ast::value,
"Expected integer constant")?;
- let val = val as lex::value;
+ let val = val as ast::value;
synassert(lex::mkloc(lexer), val is i64,
"Expected integer constant")?;
yield ast::expr {
diff --git a/hare/types/+test.ha b/hare/types/+test.ha
@@ -41,7 +41,7 @@ fn resolve(
expr: const *ast::expr,
) (size | deferred | error) = {
let expr = expr.expr as ast::constant_expr;
- let val = expr as lex::value;
+ let val = expr as ast::value;
let ival = val as i64;
assert(ival >= 0);
return ival: size;
diff --git a/hare/unit/expr.ha b/hare/unit/expr.ha
@@ -1,3 +1,4 @@
+use hare::ast;
use hare::lex;
use hare::types;
@@ -10,8 +11,5 @@ export type expr = struct {
expr: (constant_expr | void),
};
-// The value "null".
-export type _null = void;
-
// The value of a constant expression.
-export type constant_expr = (void | bool | _null | lex::value); // TODO: composite types
+export type constant_expr = ast::value; // TODO: composite types
diff --git a/hare/unit/process.ha b/hare/unit/process.ha
@@ -105,27 +105,17 @@ fn process_constant(ctx: *context, aexpr: *ast::expr) (*expr | error) = {
const constexpr = aexpr.expr as ast::constant_expr;
// TODO: Tuple unpacking
const er: (const *types::_type, constant_expr) = match (constexpr) {
- void => (
- types::lookup_builtin(ctx.store, ast::builtin_type::VOID),
- void: constant_expr,
- ),
- b: bool => (
- types::lookup_builtin(ctx.store, ast::builtin_type::BOOL),
- b,
- ),
- ast::_null => (
- types::lookup_builtin(ctx.store, ast::builtin_type::NULL),
- _null,
- ),
- v: lex::value => (
- // TODO: Constant type assignment
+ v: ast::value => (
+ // TODO: iconst/fconst lowering
types::lookup_builtin(ctx.store, match (v) {
+ ast::_null => ast::builtin_type::NULL,
+ b: bool => ast::builtin_type::BOOL,
s: str => ast::builtin_type::STR,
r: rune => ast::builtin_type::RUNE,
i: i64 => ast::builtin_type::INT,
u: u64 => ast::builtin_type::UINT,
f: f64 => ast::builtin_type::F64,
- void => abort(), // Invariant
+ void => ast::builtin_type::VOID,
}),
v,
),
@@ -172,7 +162,7 @@ fn process_constant(ctx: *context, aexpr: *ast::expr) (*expr | error) = {
assert(expr.result.repr as types::builtin == types::builtin::NULL);
assert(expr.expr is constant_expr);
- const cases: [_](str, types::builtin, lex::value) = [
+ const cases: [_](str, types::builtin, ast::value) = [
("1234", types::builtin::INT, 1234),
("1234u", types::builtin::UINT, 1234u),
("\"hello world\"", types::builtin::STR, "hello world"),
@@ -186,13 +176,12 @@ fn process_constant(ctx: *context, aexpr: *ast::expr) (*expr | error) = {
const expr = process_constant(&ctx, aexpr)!;
assert(expr.result.repr as types::builtin == case.1);
const constexpr = expr.expr as constant_expr;
- const lv = constexpr as lex::value;
match (case.2) {
- s: str => assert(lv as str == s),
- r: rune => assert(lv as rune == r),
- i: i64 => assert(lv as i64 == i),
- u: u64 => assert(lv as u64 == u),
- f: f64 => assert(lv as f64 == f),
+ s: str => assert(constexpr as str == s),
+ r: rune => assert(constexpr as rune == r),
+ i: i64 => assert(constexpr as i64 == i),
+ u: u64 => assert(constexpr as u64 == u),
+ f: f64 => assert(constexpr as f64 == f),
void => abort(),
};
};
diff --git a/hare/unparse/expr.ha b/hare/unparse/expr.ha
@@ -375,11 +375,11 @@ fn constant(
) (size | io::error) = {
return match (e) {
void => fmt::fprint(out, "void"),
- ast::_null => fmt::fprint(out, "null"),
- b: bool => fmt::fprint(out, b),
- v: lex::value => fmt::fprint(out, match (v) {
+ v: ast::value => fmt::fprint(out, match (v) {
void => abort(),
+ ast::_null => "null",
v: (i64 | u64 | f64) => v,
+ b: bool => return fmt::fprint(out, b),
// TODO: Escape these:
s: str => return fmt::fprintf(out, "\"{}\"", s),
r: rune => return fmt::fprintf(out, "'{}'", r),