v.types module
							parent
							
								
									69e9b0f250
								
							
						
					
					
						commit
						55dbb8b81c
					
				| 
						 | 
				
			
			@ -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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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"')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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