summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-07-12 15:33:02 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-07-12 15:33:02 -0400
commita919e1dbe7919a40945aa68fd05c4a658cd168a6 (patch)
tree7935d6f60832dbaa6e8ae552c5a746db94e7e713
parent07982dd332c739a8135305d22994caaa2fe340ca (diff)
fixed bin op problems, added testing types for equality
-rw-r--r--std/io.toc27
-rw-r--r--test.toc15
-rw-r--r--tokenizer.c39
-rw-r--r--types.c68
4 files changed, 98 insertions, 51 deletions
diff --git a/std/io.toc b/std/io.toc
index c61d174..10ec1d3 100644
--- a/std/io.toc
+++ b/std/io.toc
@@ -151,7 +151,6 @@ MODE_WRITE :: FileMode = 2;
IO_DEBUG ::= base.DEBUG;
-// @TODO: flush for read files -- discard buffer
// @TODO: error flag
// @TODO: locking?
File ::= struct {
@@ -247,12 +246,12 @@ fputs ::= fn(f: &File, s: []char) err : FileError {
}
}
-writes ::= fn(s: []char) FileError {
- return fwrites(&std_out, s);
+writes ::= fn(s: []char) {
+ fwrites(&std_out, s);
}
-puts ::= fn(s: []char) FileError {
- return fputs(&std_out, s);
+puts ::= fn(s: []char) {
+ fputs(&std_out, s);
}
fwritei ::= fn(use f: &File, x: int) err : FileError {
@@ -306,14 +305,20 @@ fwritei ::= fn(use f: &File, x: int) err : FileError {
}
}
-writei ::= fn(x: int) FileError {
- return fwritei(&std_out, x);
+writei ::= fn(x: int) {
+ fwritei(&std_out, x);
}
-puti ::= fn(x: int) err : FileError {
- err = writei(x);
- if !err {
- err = writes("\n");
+puti ::= fn(x: int) {
+ writei(x);
+ writes("\n");
+}
+
+putb ::= fn(x: bool) {
+ if x {
+ writes("true\n");
+ } else {
+ writes("false\n");
}
}
diff --git a/test.toc b/test.toc
index 9df26cf..7ad22c4 100644
--- a/test.toc
+++ b/test.toc
@@ -1,9 +1,14 @@
+#include "std/io.toc", io;
+
main ::= fn() {
- foo ::= #foreign("sleep", "libc.so.6") fn(#C unsigned) #C unsigned;
- foo(1);
- bar ::= foo;
- bar(2);
- x ::= 8;
+ foo0 := int == int;
+ bar0 := int == float;
+ foo1 := &&&int == &&&u8;
+ bar1 := &&&int != &&&int;
+ io.putb(foo0);
+ io.putb(bar0);
+ io.putb(foo1);
+ io.putb(bar1);
}
//main();
diff --git a/tokenizer.c b/tokenizer.c
index c26c692..8beead9 100644
--- a/tokenizer.c
+++ b/tokenizer.c
@@ -363,26 +363,27 @@ static Status tokenize_file(Tokenizer *t, File *file) {
tokr_nextchar(t);
// octal/hexadecimal/binary (or zero)
char format = *t->s;
- if (isdigit(format)) // octal
+ if (isdigit(format)) {
+ --t->s;
+ tokenization_err(t, "Number starts with a 0. If you're trying to do an octal number, use 0o (e.g. 0o54123).");
+ goto err;
+ }
+ switch (format) {
+ case 'b':
+ base = 2;
+ tokr_nextchar(t);
+ break;
+ case 'x':
+ base = 16;
+ tokr_nextchar(t);
+ break;
+ case 'o': // also octal
base = 8;
- else {
- switch (format) {
- case 'b':
- base = 2;
- tokr_nextchar(t);
- break;
- case 'x':
- base = 16;
- tokr_nextchar(t);
- break;
- case 'o':
- base = 8;
- tokr_nextchar(t);
- break;
- default:
- // it's 0/0.something etc.
- break;
- }
+ tokr_nextchar(t);
+ break;
+ default:
+ // it's 0/0.something etc.
+ break;
}
}
while (1) {
diff --git a/types.c b/types.c
index 3d657ed..50cf18c 100644
--- a/types.c
+++ b/types.c
@@ -2612,8 +2612,30 @@ static Status types_expr(Typer *tr, Expression *e) {
} else {
// numerical binary ops
if (lhs_type->kind == TYPE_BUILTIN && type_eq_implicit(lhs_type, rhs_type)) {
- // int + int, etc.
- valid = true;
+ switch (lhs_type->builtin) {
+ case BUILTIN_I8:
+ case BUILTIN_U8:
+ case BUILTIN_I16:
+ case BUILTIN_U16:
+ case BUILTIN_I32:
+ case BUILTIN_U32:
+ case BUILTIN_I64:
+ case BUILTIN_U64:
+ case BUILTIN_F32:
+ case BUILTIN_F64:
+ case BUILTIN_CHAR:
+ case BUILTIN_BOOL:
+ valid = true;
+ break;
+ case BUILTIN_NMS:
+ case BUILTIN_VOID:
+ case BUILTIN_VARARGS:
+ valid = false;
+ break;
+ case BUILTIN_TYPE:
+ valid = (o == BINARY_EQ || o == BINARY_NE);
+ break;
+ }
}
if (o == BINARY_ADD || o == BINARY_SUB || o == BINARY_SET_ADD || o == BINARY_SET_SUB) {
if (lhs_type->kind == TYPE_PTR &&
@@ -2638,19 +2660,11 @@ static Status types_expr(Typer *tr, Expression *e) {
valid = false;
}
}
- }
- if (o == BINARY_LT || o == BINARY_GT || o == BINARY_LE || o == BINARY_GE
+ } else if (o == BINARY_LT || o == BINARY_GT || o == BINARY_LE || o == BINARY_GE
|| o == BINARY_EQ || o == BINARY_NE) {
- // comparable types
- if (type_eq_implicit(lhs_type, rhs_type)) {
- switch (lhs_type->kind) {
- case TYPE_PTR:
- case TYPE_BUILTIN: // all builtins are comparable
- valid = true;
- default:
- break;
- }
- }
+ // non-builtin comparable types
+ if (lhs_type->kind == TYPE_PTR && type_eq_implicit(lhs_type->ptr, rhs_type->ptr))
+ valid = true;
}
}
if (valid) {
@@ -2664,17 +2678,38 @@ static Status types_expr(Typer *tr, Expression *e) {
case BINARY_GT:
case BINARY_LE:
case BINARY_GE:
+ t->kind = TYPE_BUILTIN;
+ t->builtin = BUILTIN_BOOL;
+ break;
case BINARY_EQ:
case BINARY_NE:
t->kind = TYPE_BUILTIN;
t->builtin = BUILTIN_BOOL;
+ if (type_is_compileonly(lhs_type)) {
+ if (type_is_builtin(lhs_type, BUILTIN_TYPE)) {
+ // comparing two types for equality (int == int)
+ assert(type_is_builtin(rhs_type, BUILTIN_TYPE));
+ // evaluate this right now.
+ Value lhs_val = {0}, rhs_val = {0};
+ if (!eval_expr(tr->evalr, lhs, &lhs_val)) return false;
+ if (!eval_expr(tr->evalr, rhs, &rhs_val)) return false;
+ e->kind = EXPR_VAL;
+ bool equal = type_eq_exact(lhs_val.type, rhs_val.type);
+ if (o == BINARY_NE)
+ e->val.boolv = !equal;
+ else
+ e->val.boolv = equal;
+ } else {
+ valid = false;
+ }
+ }
break;
default: {
if (t->kind == TYPE_UNKNOWN) { // have not yet determined type
*t = *overriding_type(lhs_type, rhs_type);
if ((o == BINARY_MOD || o == BINARY_SET_MOD)
&& type_builtin_is_float(t->builtin)) {
- err_print(e->where, "Cannot use operator % on floating-point numbers.");
+ err_print(e->where, "Cannot use operator %% on floating-point numbers.");
errored = true;
valid = false;
}
@@ -2682,7 +2717,8 @@ static Status types_expr(Typer *tr, Expression *e) {
} break;
}
}
- if (!valid) {
+ if (!valid) { // this can't just be an else; we sometimes modify valid in block above
+ t->kind = TYPE_UNKNOWN;
if (!errored) {
char *s1, *s2;
s1 = type_to_str(lhs_type);