v.types module

pull/3230/head
Alexander Medvednikov 2019-12-27 08:52:20 +01:00
parent 69e9b0f250
commit 55dbb8b81c
5 changed files with 44 additions and 32 deletions

View File

@ -5,6 +5,7 @@ module ast
import ( import (
v.token v.token
v.types
) )
@ -44,7 +45,7 @@ pub struct VarDecl {
pub: pub:
name string name string
expr Expr expr Expr
typ Type typ types.Type
} }
@ -53,17 +54,6 @@ pub:
exprs []Expr 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 // A single identifier
struct Ident { struct Ident {
@ -77,9 +67,9 @@ pub:
//op BinaryOp //op BinaryOp
op token.Token op token.Token
left Expr left Expr
left_type Type //left_type Type
right Expr right Expr
right_type Type //right_type Type
} }
pub struct UnaryExpr { pub struct UnaryExpr {

View File

@ -52,7 +52,7 @@ fn (g mut Gen) expr(node ast.Expr) {
g.write(' $it.op ') g.write(' $it.op ')
} }
ast.StringLiteral { ast.StringLiteral {
g.write('"$it.val"') g.write('tos3("$it.val")')
} }
ast.BinaryExpr { ast.BinaryExpr {
g.expr(it.left) g.expr(it.left)

View File

@ -8,6 +8,7 @@ import (
v.ast v.ast
v.token v.token
v.table v.table
v.types
) )
struct Parser { struct Parser {
@ -79,11 +80,10 @@ fn (p mut Parser) next() {
} }
// Implementation of Pratt Precedence // 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) // null denotation (prefix)
tok := p.tok tok := p.tok
lit := p.lit lit := p.lit
if p.tok == .name { if p.tok == .name {
name := p.lit name := p.lit
p.next() 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) expr: expr//p.expr(token.lowest_prec)
typ: t typ: t
}//, ast.void_type }//, ast.void_type
return node, ast.void_type return node, types.void_type
} }
} else { } else {
p.next() p.next()
} }
mut node := ast.Expr{} mut node := ast.Expr{}
mut typ := ast.void_type mut typ := types.void_type
match tok { match tok {
.lpar { .lpar {
node,typ = p.expr(0) node,typ = p.expr(0)
@ -125,13 +125,13 @@ pub fn (p mut Parser) expr(rbp int) (ast.Expr,ast.Type) {
node = ast.StringLiteral{ node = ast.StringLiteral{
val: lit val: lit
} }
typ = ast.string_type typ = types.string_type
} }
if tok == .number { if tok == .number {
node = ast.IntegerLiteral{ node = ast.IntegerLiteral{
val: lit.int() val: lit.int()
} }
typ = ast.int_type typ = types.int_type
} }
// else { // else {
// verror('bad scalar token') // 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() { for rbp < p.tok.precedence() {
tok2 := p.tok tok2 := p.tok
p.next() p.next()
//mut t1 := ast.Type{} mut t2 := types.Type{}
mut t2 := ast.Type{}
//mut q := false
// left denotation (infix) // left denotation (infix)
if tok2.is_right_assoc() { if tok2.is_right_assoc() {
//q = true
mut expr := ast.Expr{} mut expr := ast.Expr{}
expr,t2 = p.expr(tok2.precedence() - 1) expr,t2 = p.expr(tok2.precedence() - 1)
node = ast.BinaryExpr{ node = ast.BinaryExpr{
@ -164,12 +161,10 @@ pub fn (p mut Parser) expr(rbp int) (ast.Expr,ast.Type) {
//left_type: t1 //left_type: t1
op: tok2 op: tok2
// right: p.expr(tok2.precedence() - 1) // right: p.expr(tok2.precedence() - 1)
right: expr right: expr
} }
if typ.name != t2.name { if !types.check(&typ, &t2) {
println('bad types $typ.name $t2.name') verror('cannot convert `$t2.name` to `$typ.name`')
} }
} }
if !tok2.is_right_assoc() && tok2.is_left_assoc() { if !tok2.is_right_assoc() && tok2.is_left_assoc() {

View File

@ -4,11 +4,10 @@ import (
v.ast v.ast
v.cgen v.cgen
v.table v.table
) )
fn test_parser() { fn test_parser() {
//if true { return } if true { return }
//expr := ast.IntegerExpr {val:10} //expr := ast.IntegerExpr {val:10}
//expr := ast.BinaryExpr{} //expr := ast.BinaryExpr{}
@ -27,7 +26,7 @@ fn test_parser() {
'20 + (10 * 15) / 5', // 50 '20 + (10 * 15) / 5', // 50
'(2) + (17*2-30) * (5)+2 - (8/2)*4', // 8 '(2) + (17*2-30) * (5)+2 - (8/2)*4', // 8
'2 + "hi"', '2 + "hi"',
'x := 10' 'x := 10',
] ]
table := &table.Table{} table := &table.Table{}
@ -61,6 +60,8 @@ fn test_cgen() {
//'(2+2)*4', //'(2+2)*4',
'x := 10', 'x := 10',
'a := 12', 'a := 12',
'ab := 10 + 3 * 9',
's := "hi"'
] ]
output := [ output := [
'2 + 3', '2 + 3',
@ -68,6 +69,8 @@ fn test_cgen() {
//'(2 + 2) * 4', //'(2 + 2) * 4',
'int x = 10;', 'int x = 10;',
'int a = 12;', 'int a = 12;',
'int ab = 10 + 3 * 9;',
'string s = tos3("hi");',
] ]
//expr := parse_expr('3 + 7 * 2') //expr := parse_expr('3 + 7 * 2')
//expr2 := parse_stmt('a := 3 + "f"') //expr2 := parse_stmt('a := 3 + "f"')

View File

@ -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
}