boolean-type from comparisons
This commit is contained in:
24
lexer.v
24
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
|
||||
|
||||
6
main.v
6
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)
|
||||
}
|
||||
|
||||
24
parser.v
24
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,8 +265,12 @@ 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}')
|
||||
}
|
||||
if expr.op in ['<=', '==', '>=', '!='] {
|
||||
'bool'
|
||||
} else {
|
||||
left_t
|
||||
}
|
||||
}
|
||||
Variable {
|
||||
p.dump_stmt()
|
||||
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 {
|
||||
legal_ops := match type {
|
||||
'int' {['+', '-', '*', '/', '<', '>', '=']}
|
||||
'real' {['+', '-', '*', '/', '<', '>', '=']}
|
||||
global := ['=', '==', '!=']
|
||||
mut legal_ops := match type {
|
||||
'int' {['+', '-', '*', '/', '<', '>', '<=', '>=',]}
|
||||
'real' {['+', '-', '*', '/', '<', '>', '<=', '>=']}
|
||||
'bool' {['=']}
|
||||
else {[]}
|
||||
}
|
||||
legal_ops << global
|
||||
return op in legal_ops
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user