1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

fn call + fn args

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

View File

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

View File

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

View File

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

View File

@ -122,7 +122,7 @@ fn (p mut Parser) next() {
fn (p mut Parser) check(expected token.TokenKind) { fn (p mut Parser) check(expected token.TokenKind) {
if p.tok.kind != expected { if p.tok.kind != expected {
s := 'syntax error: unexpected `${p.tok.kind.str()}`, expecting `${expected.str()}`' s := 'syntax error: unexpected `${p.tok.kind.str()}`, expecting `${expected.str()}`'
verror(s) p.error(s)
} }
p.next() p.next()
} }
@ -204,6 +204,37 @@ pub fn (p mut Parser) expr(rbp int) (ast.Expr,types.Type) {
mut typ := types.void_type mut typ := types.void_type
match p.tok.kind { match p.tok.kind {
.name { .name {
/*
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 // name expr
node = ast.Ident{ node = ast.Ident{
name: p.tok.lit name: p.tok.lit
@ -211,6 +242,7 @@ pub fn (p mut Parser) expr(rbp int) (ast.Expr,types.Type) {
typ = types.int_type typ = types.int_type
p.next() p.next()
} }
}
.str { .str {
node,typ = p.parse_string_literal() node,typ = p.parse_string_literal()
} }
@ -251,7 +283,7 @@ pub fn (p mut Parser) expr(rbp int) (ast.Expr,types.Type) {
right: expr right: expr
} }
if !types.check(&typ, &t2) { 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() { else if prev_tok.is_left_assoc() {
@ -316,6 +348,21 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
// println('fn decl $name') // println('fn decl $name')
p.check(.name) p.check(.name)
p.check(.lpar) 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) p.check(.rpar)
// Return type // Return type
mut typ := types.void_type mut typ := types.void_type
@ -324,12 +371,17 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
p.return_type = typ p.return_type = typ
} }
p.check(.lcbr) p.check(.lcbr)
p.table.register_fn(table.Fn{
name: name
args: args
})
// p.check(.rcbr) // p.check(.rcbr)
stmts := p.parse_block() stmts := p.parse_block()
return ast.FnDecl{ return ast.FnDecl{
name: name name: name
stmts: stmts stmts: stmts
typ: typ typ: typ
args: ast_args
} }
} }
@ -338,7 +390,7 @@ fn (p mut Parser) return_stmt() ast.Return {
p.next() p.next()
expr,t := p.expr(0) expr,t := p.expr(0)
if !types.check(p.return_type, t) { if !types.check(p.return_type, t) {
verror('bad ret type') p.error('bad ret type')
} }
return ast.Return{ return ast.Return{
expr: expr expr: expr

View File

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

View File

@ -1,16 +1,29 @@
module table module table
import (
v.types
)
pub struct Table { pub struct Table {
pub mut: pub mut:
local_vars []Var local_vars []Var
// fns Hashmap
fns map[string]Fn
} }
pub struct Var { pub struct Var {
pub: pub:
name string name string
typ types.Type
is_mut bool is_mut bool
} }
pub struct Fn {
pub:
name string
args []Var
}
pub fn (t &Table) find_var(name string) ?Var { pub fn (t &Table) find_var(name string) ?Var {
/* /*
for i in 0 .. p.var_idx { 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 t.local_vars << v
/* /*
mut new_var := { 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
}