summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-01-04 17:44:16 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-01-04 17:44:16 -0500
commit17e7ff348aaacfebc1b2512ca69ed4348d3dd92a (patch)
treeba837910a3d259291622508a809142e77862f9e4
parent1b0ee77dcbbd50b691f7cae99a752304b3798c81 (diff)
finished export_expr
-rw-r--r--package.c43
-rw-r--r--test.toc9
-rw-r--r--types.h2
3 files changed, 51 insertions, 3 deletions
diff --git a/package.c b/package.c
index ccb4ffc..deaa06c 100644
--- a/package.c
+++ b/package.c
@@ -67,6 +67,14 @@ static inline void export_ident(Exporter *ex, Identifier i) {
export_vlq(ex, (U64)i->id);
}
+static inline void export_optional_ident(Exporter *ex, Identifier i) {
+ bool has_i = i != NULL;
+ export_bool(ex, has_i);
+ if (has_i) {
+ export_ident(ex, i);
+ }
+}
+
static inline void export_len(Exporter *ex, size_t len) {
export_vlq(ex, (U64)len);
}
@@ -219,10 +227,20 @@ static bool export_val_ptr(Exporter *ex, void *val, Type *type, Location where)
return true;
}
-static bool export_val(Exporter *ex, Value val, Type *type, Location where) {
+static inline bool export_val(Exporter *ex, Value val, Type *type, Location where) {
return export_val_ptr(ex, val_get_ptr(&val, type), type, where);
}
+static inline bool export_optional_val(Exporter *ex, Value *val, Type *type, Location where) {
+ bool has_val = val != NULL;
+ export_bool(ex, has_val);
+ if (has_val) {
+ return export_val(ex, *val, type, where);
+ } else {
+ return true;
+ }
+}
+
/* e can be NULL! */
static inline bool export_optional_expr(Exporter *ex, Expression *e) {
bool has_e = e != NULL;
@@ -353,6 +371,29 @@ static bool export_expr(Exporter *ex, Expression *e) {
if (!export_optional_expr(ex, s->to))
return false;
} break;
+ case EXPR_EACH: {
+ EachExpr *ea = e->each;
+ export_u8(ex, ea->flags);
+ if (!export_type(ex, &ea->type, e->where))
+ return false;
+ export_optional_ident(ex, ea->index);
+ export_optional_ident(ex, ea->value);
+
+ if (ea->flags & EACH_IS_RANGE) {
+ if (!export_expr(ex, ea->range.from))
+ return false;
+ if (!export_optional_expr(ex, ea->range.to))
+ return false;
+ if (!export_optional_val(ex, ea->range.stepval, &ea->type, e->where))
+ return false;
+ } else {
+ if (!export_expr(ex, ea->of))
+ return false;
+ }
+
+ if (!export_block(ex, &ea->body))
+ return false;
+ } break;
case EXPR_DSIZEOF:
case EXPR_DALIGNOF:
assert(0);
diff --git a/test.toc b/test.toc
index d4726ff..f7db673 100644
--- a/test.toc
+++ b/test.toc
@@ -1,5 +1,5 @@
Foo ::= struct {
- x: u8;
+ x: int;
};
#export main ::= fn() Foo {
g ::= fn() int { 3 };
@@ -7,5 +7,12 @@ Foo ::= struct {
b := a[1:3];
b[0] = 7;
f: Foo;
+ each i, j := b {
+ f.x += i + j;
+ }
+ each k := 10..100 {
+ f.x += k;
+ }
+
f
}; \ No newline at end of file
diff --git a/types.h b/types.h
index 9100652..e608950 100644
--- a/types.h
+++ b/types.h
@@ -527,7 +527,7 @@ enum {
};
typedef struct EachExpr {
- U16 flags;
+ U8 flags;
struct {
IdentID id;
} c;