handle unknown functions; fix var types
parent
0bd84e8060
commit
e7e07be38c
|
@ -63,7 +63,9 @@ fn (p mut Parser) bool_expression() string {
|
|||
// `as` cast
|
||||
// TODO remove copypasta
|
||||
if p.tok == .key_as {
|
||||
p.fspace()
|
||||
p.next()
|
||||
p.fspace()
|
||||
cast_typ := p.get_type()
|
||||
if typ == cast_typ {
|
||||
p.warn('casting `$typ` to `$cast_typ` is not needed')
|
||||
|
|
|
@ -94,6 +94,7 @@ pub struct CallExpr {
|
|||
pub:
|
||||
name string
|
||||
args []Expr
|
||||
is_unknown bool
|
||||
}
|
||||
|
||||
pub struct Return {
|
||||
|
|
|
@ -17,6 +17,12 @@ void init_user() {
|
|||
};
|
||||
}
|
||||
|
||||
User get_user() {
|
||||
User user = (User){
|
||||
};
|
||||
return user;
|
||||
}
|
||||
|
||||
void puts(string s) {
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
fn function1() int {
|
||||
a := 10 + 1
|
||||
b := a + 1
|
||||
//return a
|
||||
return 0
|
||||
}
|
||||
|
||||
|
@ -18,6 +19,12 @@ fn init_user() {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_user() User {
|
||||
user := User{}
|
||||
return user
|
||||
}
|
||||
|
||||
|
||||
fn puts(s string) {}
|
||||
|
||||
// comment
|
||||
|
|
|
@ -34,34 +34,6 @@ pub fn parse_stmt(text string, table &table.Table) ast.Stmt {
|
|||
return p.stmt()
|
||||
}
|
||||
|
||||
pub fn (p mut Parser) get_type() types.Type {
|
||||
defer {
|
||||
p.next()
|
||||
}
|
||||
match p.tok.lit {
|
||||
'int' {
|
||||
return types.int_type
|
||||
}
|
||||
'f64' {
|
||||
return types.f64_type
|
||||
}
|
||||
'string' {
|
||||
return types.string_type
|
||||
}
|
||||
'voidptr' {
|
||||
return types.voidptr_type
|
||||
}
|
||||
else {
|
||||
typ := p.table.types[p.tok.lit]
|
||||
if isnil(typ.name.str) || typ.name == '' {
|
||||
p.error('undefined type `$p.tok.lit`')
|
||||
}
|
||||
println('RET Typ $typ.name')
|
||||
return typ
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_file(path string, table &table.Table) ast.File {
|
||||
text := os.read_file(path) or {
|
||||
panic(err)
|
||||
|
@ -123,6 +95,33 @@ pub fn parse_files(paths []string, table &table.Table) []ast.File {
|
|||
return files
|
||||
}
|
||||
|
||||
pub fn (p mut Parser) parse_type() types.Type {
|
||||
defer {
|
||||
p.next()
|
||||
}
|
||||
match p.tok.lit {
|
||||
'int' {
|
||||
return types.int_type
|
||||
}
|
||||
'f64' {
|
||||
return types.f64_type
|
||||
}
|
||||
'string' {
|
||||
return types.string_type
|
||||
}
|
||||
'voidptr' {
|
||||
return types.voidptr_type
|
||||
}
|
||||
else {
|
||||
typ := p.table.types[p.tok.lit]
|
||||
if isnil(typ.name.str) || typ.name == '' {
|
||||
p.error('undefined type `$p.tok.lit`')
|
||||
}
|
||||
return typ
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (p mut Parser) read_first_token() {
|
||||
// need to call next() twice to get peek token and current token
|
||||
p.next()
|
||||
|
@ -268,6 +267,7 @@ pub fn (p mut Parser) call_expr() (ast.CallExpr,types.Type) {
|
|||
// println('got fn call')
|
||||
fn_name := p.check_name()
|
||||
p.check(.lpar)
|
||||
mut is_unknown := false
|
||||
mut args := []ast.Expr
|
||||
if f := p.table.find_fn(fn_name) {
|
||||
for i, arg in f.args {
|
||||
|
@ -284,12 +284,23 @@ pub fn (p mut Parser) call_expr() (ast.CallExpr,types.Type) {
|
|||
p.error('too many arguments in call to `$fn_name`')
|
||||
}
|
||||
}else{
|
||||
p.error('unknown function `$fn_name`')
|
||||
is_unknown = true
|
||||
p.warn('unknown function `$fn_name`')
|
||||
for p.tok.kind != .rpar {
|
||||
p.expr(0)
|
||||
if p.tok.kind != .rpar {
|
||||
p.check(.comma)
|
||||
}
|
||||
}
|
||||
}
|
||||
p.check(.rpar)
|
||||
node := ast.CallExpr{
|
||||
name: fn_name
|
||||
args: args
|
||||
is_unknown: is_unknown
|
||||
}
|
||||
if is_unknown {
|
||||
p.table.unknown_calls << node
|
||||
}
|
||||
return node,types.int_type
|
||||
}
|
||||
|
@ -317,7 +328,8 @@ pub fn (p mut Parser) expr(rbp int) (ast.Expr,types.Type) {
|
|||
}
|
||||
// struct init
|
||||
else if p.peek_tok.kind == .lcbr {
|
||||
typ = p.get_type()
|
||||
typ = p.parse_type()
|
||||
// println('sturct init typ=$typ.name')
|
||||
p.check(.lcbr)
|
||||
mut field_names := []string
|
||||
mut exprs := []ast.Expr
|
||||
|
@ -342,7 +354,12 @@ pub fn (p mut Parser) expr(rbp int) (ast.Expr,types.Type) {
|
|||
node = ast.Ident{
|
||||
name: p.tok.lit
|
||||
}
|
||||
typ = types.int_type
|
||||
var := p.table.find_var(p.tok.lit) or {
|
||||
p.error('unknown variable `$p.tok.lit`')
|
||||
exit(0)
|
||||
}
|
||||
typ = var.typ
|
||||
// ///typ = types.int_type
|
||||
p.next()
|
||||
}
|
||||
}
|
||||
|
@ -577,7 +594,7 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
|
|||
p.check(.colon)
|
||||
}
|
||||
field_name := p.check_name()
|
||||
typ := p.get_type()
|
||||
typ := p.parse_type()
|
||||
fields << ast.Field{
|
||||
name: field_name
|
||||
typ: typ
|
||||
|
@ -605,7 +622,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
|
|||
mut ast_args := []ast.Arg
|
||||
for p.tok.kind != .rpar {
|
||||
arg_name := p.check_name()
|
||||
typ := p.get_type()
|
||||
typ := p.parse_type()
|
||||
args << table.Var{
|
||||
name: arg_name
|
||||
typ: typ
|
||||
|
@ -622,7 +639,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
|
|||
// Return type
|
||||
mut typ := types.void_type
|
||||
if p.tok.kind == .name {
|
||||
typ = p.get_type()
|
||||
typ = p.parse_type()
|
||||
p.return_type = typ
|
||||
}
|
||||
p.table.register_fn(table.Fn{
|
||||
|
@ -642,7 +659,7 @@ fn (p mut Parser) return_stmt() ast.Return {
|
|||
p.next()
|
||||
expr,t := p.expr(0)
|
||||
if !types.check(p.return_type, t) {
|
||||
p.error('bad ret type')
|
||||
p.error('cannot use `$t.name` as type `$p.return_type.name` in return argument')
|
||||
}
|
||||
return ast.Return{
|
||||
expr: expr
|
||||
|
@ -668,6 +685,7 @@ fn (p mut Parser) var_decl() ast.VarDecl {
|
|||
}
|
||||
p.table.register_var(table.Var{
|
||||
name: name
|
||||
typ: t
|
||||
is_mut: is_mut
|
||||
})
|
||||
// println(p.table.names)
|
||||
|
|
|
@ -2,6 +2,7 @@ module table
|
|||
|
||||
import (
|
||||
v.types
|
||||
v.ast
|
||||
)
|
||||
|
||||
pub struct Table {
|
||||
|
@ -10,6 +11,8 @@ pub mut:
|
|||
// fns Hashmap
|
||||
fns map[string]Fn
|
||||
types map[string]types.Type
|
||||
//
|
||||
unknown_calls []ast.CallExpr
|
||||
}
|
||||
|
||||
pub struct Var {
|
||||
|
|
Loading…
Reference in New Issue