v.types module
parent
69e9b0f250
commit
55dbb8b81c
vlib/v
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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"')
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue