fn call + fn args

pull/3253/head
Alexander Medvednikov 2019-12-29 07:24:17 +01:00
parent c915c58d12
commit 349576b5cd
7 changed files with 126 additions and 17 deletions

View File

@ -8,8 +8,8 @@ import (
v.types
)
pub type Expr = BinaryExpr | UnaryExpr | IfExpr | StringLiteral | IntegerLiteral | FloatLiteral |
Ident
pub type Expr = BinaryExpr | UnaryExpr | IfExpr | StringLiteral | IntegerLiteral |
FloatLiteral | Ident | CallExpr
pub type Stmt = VarDecl | FnDecl | Return | Module | Import | ExprStmt | AssignStmt
// Stand-alone expression in a statement list.
@ -50,12 +50,24 @@ pub:
// imports map[string]string
}
pub struct Arg {
pub:
typ types.Type
name string
}
pub struct FnDecl {
pub:
name string
stmts []Stmt
// exprs []Expr
typ types.Type
args []Arg
}
pub struct CallExpr {
pub:
name string
args []Expr
}
pub struct Return {

View File

@ -39,7 +39,11 @@ fn (g mut Gen) stmt(node ast.Stmt) {
g.writeln(';')
}
ast.FnDecl {
g.writeln('$it.typ.name ${it.name}() { ')
g.write('$it.typ.name ${it.name}(')
for arg in it.args {
g.write(arg.typ.name + ' ' + arg.name)
}
g.writeln(') { ')
for stmt in it.stmts {
g.stmt(stmt)
}
@ -109,6 +113,9 @@ fn (g mut Gen) expr(node ast.Expr) {
// verror('bad types $typ.name $typ2.name')
// }
}
ast.CallExpr {
g.write('${it.name}()')
}
ast.Ident {
g.write('$it.name')
}

View File

@ -4,6 +4,9 @@ int function1() {
return 0;
}
void foo(int a) {
}
void function2() {
int x = 0;
f64 f = 10.1;
@ -12,4 +15,6 @@ void function2() {
x += 10;
x += 1;
m += 2;
function1();
}

View File

@ -4,6 +4,10 @@ fn function1() int {
return 0
}
fn foo(a int) {
}
// comment
fn function2() {
mut x := 0
@ -13,6 +17,8 @@ fn function2() {
x += 10
x += 1
m += 2
function1()
//a += 1
//c := 0
}

View File

@ -122,7 +122,7 @@ fn (p mut Parser) next() {
fn (p mut Parser) check(expected token.TokenKind) {
if p.tok.kind != expected {
s := 'syntax error: unexpected `${p.tok.kind.str()}`, expecting `${expected.str()}`'
verror(s)
p.error(s)
}
p.next()
}
@ -171,7 +171,7 @@ pub fn (p mut Parser) stmt() ast.Stmt {
pub fn (p mut Parser) assign_stmt() ast.AssignStmt {
name := p.tok.lit
//println('looking for $name')
// println('looking for $name')
var := p.table.find_var(name) or {
p.error('unknown variable `$name`')
exit(1)
@ -181,7 +181,7 @@ pub fn (p mut Parser) assign_stmt() ast.AssignStmt {
}
left_expr,left_type := p.expr(0)
op := p.tok.kind
//println('assignn_stmt() ' + op.str())
// println('assignn_stmt() ' + op.str())
p.next()
right_expr,right_type := p.expr(0)
return ast.AssignStmt{
@ -204,12 +204,44 @@ pub fn (p mut Parser) expr(rbp int) (ast.Expr,types.Type) {
mut typ := types.void_type
match p.tok.kind {
.name {
// name expr
node = ast.Ident{
name: p.tok.lit
/*
sym := p.table.find_symbol(p.tok.lit)
if sym.cat == .function {
return
}
*/
// fn call
if p.peek_tok.kind == .lpar {
println('got fn call')
fn_name := p.tok.lit
f := p.table.find_fn(fn_name) or {
p.error('unknown fucntion `$p.tok.lit`')
exit(0)
}
p.check(.name)
p.check(.lpar)
mut args := []ast.Expr
for _ in 0 .. f.args.len {
e,_ := p.expr(0)
args << e
p.check(.comma)
}
p.check(.rpar)
node = ast.CallExpr{
name: fn_name
args: args
}
typ = types.int_type
}
else {
// name expr
node = ast.Ident{
name: p.tok.lit
}
typ = types.int_type
p.next()
}
typ = types.int_type
p.next()
}
.str {
node,typ = p.parse_string_literal()
@ -251,7 +283,7 @@ pub fn (p mut Parser) expr(rbp int) (ast.Expr,types.Type) {
right: expr
}
if !types.check(&typ, &t2) {
verror('cannot convert `$t2.name` to `$typ.name`')
p.error('cannot convert `$t2.name` to `$typ.name`')
}
}
else if prev_tok.is_left_assoc() {
@ -316,6 +348,21 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
// println('fn decl $name')
p.check(.name)
p.check(.lpar)
// Args
mut args := []table.Var
mut ast_args := []ast.Arg
for p.tok.kind != .rpar {
arg_name := p.check_name()
typ := p.get_type()
args << table.Var{
name: arg_name
typ: typ
}
ast_args << ast.Arg{
typ: typ
name: arg_name
}
}
p.check(.rpar)
// Return type
mut typ := types.void_type
@ -324,12 +371,17 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
p.return_type = typ
}
p.check(.lcbr)
p.table.register_fn(table.Fn{
name: name
args: args
})
// p.check(.rcbr)
stmts := p.parse_block()
return ast.FnDecl{
name: name
stmts: stmts
typ: typ
args: ast_args
}
}
@ -338,7 +390,7 @@ fn (p mut Parser) return_stmt() ast.Return {
p.next()
expr,t := p.expr(0)
if !types.check(p.return_type, t) {
verror('bad ret type')
p.error('bad ret type')
}
return ast.Return{
expr: expr
@ -371,7 +423,7 @@ fn (p mut Parser) var_decl() ast.VarDecl {
return ast.VarDecl{
name: name
expr: expr // p.expr(token.lowest_prec)
typ: t
}
}

View File

@ -36,7 +36,7 @@ fn test_parse_expr() {
'2+2*4',
// '(2+2)*4',
'x := 10',
'a := 12',
'mut a := 12',
'ab := 10 + 3 * 9',
's := "hi"',
// '1 += 2',

View File

@ -1,16 +1,29 @@
module table
import (
v.types
)
pub struct Table {
pub mut:
local_vars []Var
// fns Hashmap
fns map[string]Fn
}
pub struct Var {
pub:
name string
typ types.Type
is_mut bool
}
pub struct Fn {
pub:
name string
args []Var
}
pub fn (t &Table) find_var(name string) ?Var {
/*
for i in 0 .. p.var_idx {
@ -40,7 +53,7 @@ pub fn (t mut Table) clear_vars() {
}
}
fn (t mut Table) register_var(v Var) {
pub fn (t mut Table) register_var(v Var) {
t.local_vars << v
/*
mut new_var := {
@ -63,3 +76,17 @@ fn (t mut Table) register_var(v Var) {
*/
}
pub fn (t &Table) find_fn(name string) ?Fn {
f := t.fns[name]
if f.name.str != 0 {
// TODO
return f
}
return none
}
pub fn (t mut Table) register_fn(new_fn Fn) {
// println('reg fn $new_fn.name nr_args=$new_fn.args.len')
t.fns[new_fn.name] = new_fn
}