diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index e7046ba68c..0fa347267d 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -5,6 +5,7 @@ module ast import ( v.token + v.types ) @@ -44,7 +45,7 @@ pub struct VarDecl { pub: name string expr Expr - typ Type + typ types.Type } @@ -53,17 +54,6 @@ pub: exprs []Expr } -pub struct Type { -pub: - name string -} - -pub const ( - string_type = Type{'string'} - int_type = Type{'int'} - void_type = Type{'void'} -) - // A single identifier struct Ident { @@ -77,9 +67,9 @@ pub: //op BinaryOp op token.Token left Expr - left_type Type + //left_type Type right Expr - right_type Type + //right_type Type } pub struct UnaryExpr { diff --git a/vlib/v/cgen/cgen.v b/vlib/v/cgen/cgen.v index 6a65325818..5179bb8be7 100644 --- a/vlib/v/cgen/cgen.v +++ b/vlib/v/cgen/cgen.v @@ -52,7 +52,7 @@ fn (g mut Gen) expr(node ast.Expr) { g.write(' $it.op ') } ast.StringLiteral { - g.write('"$it.val"') + g.write('tos3("$it.val")') } ast.BinaryExpr { g.expr(it.left) diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index cb1d89e98a..820f526444 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -8,6 +8,7 @@ import ( v.ast v.token v.table + v.types ) struct Parser { @@ -79,11 +80,10 @@ fn (p mut Parser) next() { } // Implementation of Pratt Precedence -pub fn (p mut Parser) expr(rbp int) (ast.Expr,ast.Type) { +pub fn (p mut Parser) expr(rbp int) (ast.Expr,types.Type) { // null denotation (prefix) tok := p.tok lit := p.lit - if p.tok == .name { name := p.lit p.next() @@ -103,13 +103,13 @@ pub fn (p mut Parser) expr(rbp int) (ast.Expr,ast.Type) { expr: expr//p.expr(token.lowest_prec) typ: t }//, ast.void_type - return node, ast.void_type + return node, types.void_type } } else { p.next() } mut node := ast.Expr{} - mut typ := ast.void_type + mut typ := types.void_type match tok { .lpar { node,typ = p.expr(0) @@ -125,13 +125,13 @@ pub fn (p mut Parser) expr(rbp int) (ast.Expr,ast.Type) { node = ast.StringLiteral{ val: lit } - typ = ast.string_type + typ = types.string_type } if tok == .number { node = ast.IntegerLiteral{ val: lit.int() } - typ = ast.int_type + typ = types.int_type } // else { // verror('bad scalar token') @@ -151,12 +151,9 @@ pub fn (p mut Parser) expr(rbp int) (ast.Expr,ast.Type) { for rbp < p.tok.precedence() { tok2 := p.tok p.next() - //mut t1 := ast.Type{} - mut t2 := ast.Type{} - //mut q := false + mut t2 := types.Type{} // left denotation (infix) if tok2.is_right_assoc() { - //q = true mut expr := ast.Expr{} expr,t2 = p.expr(tok2.precedence() - 1) node = ast.BinaryExpr{ @@ -164,12 +161,10 @@ pub fn (p mut Parser) expr(rbp int) (ast.Expr,ast.Type) { //left_type: t1 op: tok2 // right: p.expr(tok2.precedence() - 1) - right: expr - } - if typ.name != t2.name { - println('bad types $typ.name $t2.name') + if !types.check(&typ, &t2) { + verror('cannot convert `$t2.name` to `$typ.name`') } } if !tok2.is_right_assoc() && tok2.is_left_assoc() { diff --git a/vlib/v/parser/parser_test.v b/vlib/v/parser/parser_test.v index 2147e6b19c..842bc4bf49 100644 --- a/vlib/v/parser/parser_test.v +++ b/vlib/v/parser/parser_test.v @@ -4,11 +4,10 @@ import ( v.ast v.cgen v.table - ) fn test_parser() { - //if true { return } + if true { return } //expr := ast.IntegerExpr {val:10} //expr := ast.BinaryExpr{} @@ -27,7 +26,7 @@ fn test_parser() { '20 + (10 * 15) / 5', // 50 '(2) + (17*2-30) * (5)+2 - (8/2)*4', // 8 '2 + "hi"', - 'x := 10' + 'x := 10', ] table := &table.Table{} @@ -61,6 +60,8 @@ fn test_cgen() { //'(2+2)*4', 'x := 10', 'a := 12', + 'ab := 10 + 3 * 9', + 's := "hi"' ] output := [ '2 + 3', @@ -68,6 +69,8 @@ fn test_cgen() { //'(2 + 2) * 4', 'int x = 10;', 'int a = 12;', + 'int ab = 10 + 3 * 9;', + 'string s = tos3("hi");', ] //expr := parse_expr('3 + 7 * 2') //expr2 := parse_stmt('a := 3 + "f"') diff --git a/vlib/v/types/types.v b/vlib/v/types/types.v new file mode 100644 index 0000000000..81066ab7a7 --- /dev/null +++ b/vlib/v/types/types.v @@ -0,0 +1,24 @@ +// Copyright (c) 2019 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. +module types + +pub struct Type { +pub: + name string + idx int +} + +pub const ( + void_type = Type{'void', 0} + int_type = Type{'int', 1} + string_type = Type{'string', 2} +) + + +fn check(got, expected &Type) bool { + if got.idx != expected.idx { + return false + } + return true +}