diff options
-rw-r--r-- | std/io.toc | 27 | ||||
-rw-r--r-- | test.toc | 15 | ||||
-rw-r--r-- | tokenizer.c | 39 | ||||
-rw-r--r-- | types.c | 68 |
4 files changed, 98 insertions, 51 deletions
@@ -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"); } } @@ -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 != &&∫ + 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) { @@ -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); |