From fc79c23b77919f12c3f99e4ecaed832b55415bec Mon Sep 17 00:00:00 2001 From: uan Date: Wed, 4 Feb 2026 18:06:51 +0100 Subject: [PATCH] boolean-type from comparisons --- lexer.v | 24 ++++++++++++++++++++++-- main.v | 6 ++++-- parser.v | 26 +++++++++++++++----------- test.one | 2 +- 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/lexer.v b/lexer.v index 79790fc..5822f86 100644 --- a/lexer.v +++ b/lexer.v @@ -22,6 +22,10 @@ enum TokenType as u8 { equals less greater + eq_eq + greater_eq + less_eq + not_eq lparen rparen lsqparen @@ -52,7 +56,7 @@ fn str_from_toktype(type TokenType) string { .kw_else {'else'} .kw_for {'for'} .kw_break {'break'} - .kw_fn {'break'} + .kw_fn {'fn'} .kw_return {'return'} .identifier {'identifier'} .eof {'EOF'} @@ -74,6 +78,10 @@ fn str_from_toktype(type TokenType) string { .comma {'comma'} .semicolon {'semicolon'} .colon {'colon'} + .eq_eq {'eq eq'} + .greater_eq {'greater eq'} + .less_eq {'less eq'} + .not_eq {'not eq'} } } @@ -96,6 +104,10 @@ fn toktype_from_delimiter(delimiter string) TokenType { ',' {.comma} ';' {.semicolon} ':' {.colon} + '==' {.eq_eq} + '>=' {.greater_eq} + '<=' {.less_eq} + '!=' {.not_eq} else {.unknown} } } @@ -160,7 +172,15 @@ fn lex(input string) ?[]Token { } if is_delimiter(input[right], is_inside_number) && left == right { if !input[right].is_space() { - tokens << Token{toktype_from_delimiter(input[right].ascii_str()), input[right].ascii_str()} + mut tok_str := input[right].ascii_str() + if right + 1 < input.len { + combined := input.substr(right, right + 2) + if combined in ['==', '>=', '<=', '!='] { + tok_str = combined + right++ + } + } + tokens << Token{toktype_from_delimiter(tok_str), tok_str} } right++ left = right diff --git a/main.v b/main.v index 8516d44..aa8be7a 100644 --- a/main.v +++ b/main.v @@ -6,13 +6,15 @@ fn main() { content := os.read_file("test.one") or { return } println("---------\n" + content + "---------") tokens := lex(content) or { return } + println("-- TOK --") + print_toks(tokens) + mut parser := Parser{ tokens: tokens pos: 0 } statements := parser.parse_program() - println("-- TOK --") - print_toks(tokens) + println("-- AST --") println(statements) } diff --git a/parser.v b/parser.v index 33367ca..2f65d86 100644 --- a/parser.v +++ b/parser.v @@ -213,11 +213,9 @@ fn (mut p Parser) parse_expr() Expr { mut left := p.parse_primary() match p.peek().type { - .plus {return p.parse_binary(left, '+')} - .minus {return p.parse_binary(left, '-')} - .star {return p.parse_binary(left, '*')} - .slash {return p.parse_binary(left, '/')} - .equals {return p.parse_binary(left, '=')} + .plus, .minus, .star, .slash, .equals, .eq_eq, .not_eq, .less_eq, .greater_eq { + return p.parse_binary(left, p.peek().text) + } else {return left} } } @@ -226,8 +224,8 @@ fn (mut p Parser) parse_binary(left Expr, op string) BinaryExpr { p.next() right := p.parse_expr() binary_expr := BinaryExpr{left, op, right} - if !p.is_op_valid_for_type(p.get_expr_type(binary_expr), op) { - parse_error("Illegal operation ${op} for type ${p.get_expr_type(binary_expr)}") + if !p.is_op_valid_for_type(p.get_expr_type(left), op) { + parse_error("Illegal operation ${op} for type ${p.get_expr_type(left)}") } return binary_expr } @@ -267,7 +265,11 @@ fn (mut p Parser) get_expr_type(expr Expr) string { if left_t != right_t { parse_error ('Type mismatch in expression: ${left_t} and ${right_t}') } - left_t + if expr.op in ['<=', '==', '>=', '!='] { + 'bool' + } else { + left_t + } } Variable { p.dump_stmt() @@ -284,12 +286,14 @@ fn (mut p Parser) get_expr_type(expr Expr) string { } fn (mut p Parser) is_op_valid_for_type(type string, op string) bool { - legal_ops := match type { - 'int' {['+', '-', '*', '/', '<', '>', '=']} - 'real' {['+', '-', '*', '/', '<', '>', '=']} + global := ['=', '==', '!='] + mut legal_ops := match type { + 'int' {['+', '-', '*', '/', '<', '>', '<=', '>=',]} + 'real' {['+', '-', '*', '/', '<', '>', '<=', '>=']} 'bool' {['=']} else {[]} } + legal_ops << global return op in legal_ops } diff --git a/test.one b/test.one index dfc3894..916d105 100644 --- a/test.one +++ b/test.one @@ -1 +1 @@ -let a int = int((5.1 + 2.2) * 5.1); +let a bool = 2 <= 4;