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:
parent
c915c58d12
commit
349576b5cd
@ -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 {
|
||||
|
@ -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')
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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',
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user