boolean-type from comparisons

This commit is contained in:
uan
2026-02-04 18:06:51 +01:00
parent 6525fa711d
commit fc79c23b77
4 changed files with 42 additions and 16 deletions

24
lexer.v
View File

@@ -22,6 +22,10 @@ enum TokenType as u8 {
equals equals
less less
greater greater
eq_eq
greater_eq
less_eq
not_eq
lparen lparen
rparen rparen
lsqparen lsqparen
@@ -52,7 +56,7 @@ fn str_from_toktype(type TokenType) string {
.kw_else {'else'} .kw_else {'else'}
.kw_for {'for'} .kw_for {'for'}
.kw_break {'break'} .kw_break {'break'}
.kw_fn {'break'} .kw_fn {'fn'}
.kw_return {'return'} .kw_return {'return'}
.identifier {'identifier'} .identifier {'identifier'}
.eof {'EOF'} .eof {'EOF'}
@@ -74,6 +78,10 @@ fn str_from_toktype(type TokenType) string {
.comma {'comma'} .comma {'comma'}
.semicolon {'semicolon'} .semicolon {'semicolon'}
.colon {'colon'} .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} ',' {.comma}
';' {.semicolon} ';' {.semicolon}
':' {.colon} ':' {.colon}
'==' {.eq_eq}
'>=' {.greater_eq}
'<=' {.less_eq}
'!=' {.not_eq}
else {.unknown} else {.unknown}
} }
} }
@@ -160,7 +172,15 @@ fn lex(input string) ?[]Token {
} }
if is_delimiter(input[right], is_inside_number) && left == right { if is_delimiter(input[right], is_inside_number) && left == right {
if !input[right].is_space() { 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++ right++
left = right left = right

6
main.v
View File

@@ -6,13 +6,15 @@ fn main() {
content := os.read_file("test.one") or { return } content := os.read_file("test.one") or { return }
println("---------\n" + content + "---------") println("---------\n" + content + "---------")
tokens := lex(content) or { return } tokens := lex(content) or { return }
println("-- TOK --")
print_toks(tokens)
mut parser := Parser{ mut parser := Parser{
tokens: tokens tokens: tokens
pos: 0 pos: 0
} }
statements := parser.parse_program() statements := parser.parse_program()
println("-- TOK --")
print_toks(tokens)
println("-- AST --") println("-- AST --")
println(statements) println(statements)
} }

View File

@@ -213,11 +213,9 @@ fn (mut p Parser) parse_expr() Expr {
mut left := p.parse_primary() mut left := p.parse_primary()
match p.peek().type { match p.peek().type {
.plus {return p.parse_binary(left, '+')} .plus, .minus, .star, .slash, .equals, .eq_eq, .not_eq, .less_eq, .greater_eq {
.minus {return p.parse_binary(left, '-')} return p.parse_binary(left, p.peek().text)
.star {return p.parse_binary(left, '*')} }
.slash {return p.parse_binary(left, '/')}
.equals {return p.parse_binary(left, '=')}
else {return left} else {return left}
} }
} }
@@ -226,8 +224,8 @@ fn (mut p Parser) parse_binary(left Expr, op string) BinaryExpr {
p.next() p.next()
right := p.parse_expr() right := p.parse_expr()
binary_expr := BinaryExpr{left, op, right} binary_expr := BinaryExpr{left, op, right}
if !p.is_op_valid_for_type(p.get_expr_type(binary_expr), op) { if !p.is_op_valid_for_type(p.get_expr_type(left), op) {
parse_error("Illegal operation ${op} for type ${p.get_expr_type(binary_expr)}") parse_error("Illegal operation ${op} for type ${p.get_expr_type(left)}")
} }
return binary_expr return binary_expr
} }
@@ -267,8 +265,12 @@ fn (mut p Parser) get_expr_type(expr Expr) string {
if left_t != right_t { if left_t != right_t {
parse_error ('Type mismatch in expression: ${left_t} and ${right_t}') parse_error ('Type mismatch in expression: ${left_t} and ${right_t}')
} }
if expr.op in ['<=', '==', '>=', '!='] {
'bool'
} else {
left_t left_t
} }
}
Variable { Variable {
p.dump_stmt() p.dump_stmt()
info := p.symbols.lookup_var(expr.name) or { info := p.symbols.lookup_var(expr.name) or {
@@ -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 { fn (mut p Parser) is_op_valid_for_type(type string, op string) bool {
legal_ops := match type { global := ['=', '==', '!=']
'int' {['+', '-', '*', '/', '<', '>', '=']} mut legal_ops := match type {
'real' {['+', '-', '*', '/', '<', '>', '=']} 'int' {['+', '-', '*', '/', '<', '>', '<=', '>=',]}
'real' {['+', '-', '*', '/', '<', '>', '<=', '>=']}
'bool' {['=']} 'bool' {['=']}
else {[]} else {[]}
} }
legal_ops << global
return op in legal_ops return op in legal_ops
} }

View File

@@ -1 +1 @@
let a int = int((5.1 + 2.2) * 5.1); let a bool = 2 <= 4;