v2: fix C function & type prefixing

pull/3880/head
Joe Conigliaro 2020-02-29 21:47:47 +11:00
parent 48f912c2e9
commit f67fca826e
5 changed files with 51 additions and 16 deletions

View File

@ -164,6 +164,17 @@ fn (c mut Checker) check_assign_expr(assign_expr ast.AssignExpr) {
pub fn (c mut Checker) call_expr(call_expr ast.CallExpr) table.Type { pub fn (c mut Checker) call_expr(call_expr ast.CallExpr) table.Type {
fn_name := call_expr.name fn_name := call_expr.name
mut found := false mut found := false
// start hack: until v1 is fixed and c definitions are added for these
if fn_name == 'C.calloc' {
return table.byteptr_type
}
else if fn_name == 'C.exit' {
return table.void_type
}
else if fn_name == 'C.free' {
return table.void_type
}
// end hack
// look for function in format `mod.fn` or `fn` (main/builtin) // look for function in format `mod.fn` or `fn` (main/builtin)
mut f := table.Fn{} mut f := table.Fn{}
if f1 := c.table.find_fn(fn_name) { if f1 := c.table.find_fn(fn_name) {
@ -722,7 +733,9 @@ pub fn (c mut Checker) enum_val(node ast.EnumVal) table.Type {
typ_idx := if node.enum_name == '' { c.expected_type } else { // typ_idx := if node.enum_name == '' { c.expected_type } else { //
c.table.find_type_idx(node.enum_name) } c.table.find_type_idx(node.enum_name) }
typ := c.table.get_type_symbol(table.Type(typ_idx)) typ := c.table.get_type_symbol(table.Type(typ_idx))
info := typ.info as table.Enum
//info := typ.info as table.Enum
info := typ.enum_info()
// rintln('checker: x = $info.x enum val $c.expected_type $typ.name') // rintln('checker: x = $info.x enum val $c.expected_type $typ.name')
// println(info.vals) // println(info.vals)
if !(node.val in info.vals) { if !(node.val in info.vals) {

View File

@ -11,11 +11,7 @@ import (
pub fn (p mut Parser) call_expr(is_c bool, mod string) ast.CallExpr { pub fn (p mut Parser) call_expr(is_c bool, mod string) ast.CallExpr {
tok := p.tok tok := p.tok
name := p.check_name() name := p.check_name()
// these fns are are not defined as C functions, but are v fns and have no C prefix fn_name := if is_c {'C.$name' } else if mod.len > 0 { '${mod}.$name' } else { name }
// but for some reason are called with the C pefix. for now add exception until fixed
v_fns_called_with_c_prefix := ['exit', 'calloc', 'free']
fn_name := if is_c && !(name in v_fns_called_with_c_prefix) {'C.$name' }
else if mod.len > 0 { '${mod}.$name' } else { name }
p.check(.lpar) p.check(.lpar)
args, muts := p.call_args() args, muts := p.call_args()
node := ast.CallExpr{ node := ast.CallExpr{

View File

@ -90,11 +90,12 @@ pub fn (p mut Parser) parse_type() table.Type {
p.check(.amp) p.check(.amp)
nr_muls++ nr_muls++
} }
if p.tok.lit == 'C' { is_c := p.tok.lit == 'C'
if is_c {
p.next() p.next()
p.check(.dot) p.check(.dot)
} }
mut typ := p.parse_any_type(nr_muls > 0) mut typ := p.parse_any_type(is_c, nr_muls > 0)
if is_optional { if is_optional {
typ = table.type_to_optional(typ) typ = table.type_to_optional(typ)
} }
@ -104,10 +105,13 @@ pub fn (p mut Parser) parse_type() table.Type {
return typ return typ
} }
pub fn (p mut Parser) parse_any_type(is_ptr bool) table.Type { pub fn (p mut Parser) parse_any_type(is_c, is_ptr bool) table.Type {
mut name := p.tok.lit mut name := p.tok.lit
if is_c {
name = 'C.$name'
}
// `module.Type` // `module.Type`
if p.peek_tok.kind == .dot { else if p.peek_tok.kind == .dot {
// /if !(p.tok.lit in p.table.imports) { // /if !(p.tok.lit in p.table.imports) {
if !p.known_import(name) { if !p.known_import(name) {
println(p.table.imports) println(p.table.imports)
@ -211,7 +215,7 @@ pub fn (p mut Parser) parse_any_type(is_ptr bool) table.Type {
// println('NOT FOUND: $name - adding placeholder - $idx') // println('NOT FOUND: $name - adding placeholder - $idx')
return table.new_type(idx) return table.new_type(idx)
} }
} }
} }
} }
} }

View File

@ -555,7 +555,9 @@ pub fn (p mut Parser) name_expr() ast.Expr {
return node return node
} }
if p.peek_tok.kind == .dot && (is_c || p.known_import(p.tok.lit) || p.mod.all_after('.') == p.tok.lit) { if p.peek_tok.kind == .dot && (is_c || p.known_import(p.tok.lit) || p.mod.all_after('.') == p.tok.lit) {
if !is_c { if is_c {
mod = 'C'
} else {
// prepend the full import // prepend the full import
mod = p.imports[p.tok.lit] mod = p.imports[p.tok.lit]
} }
@ -566,10 +568,13 @@ pub fn (p mut Parser) name_expr() ast.Expr {
// p.warn('name expr $p.tok.lit $p.peek_tok.str()') // p.warn('name expr $p.tok.lit $p.peek_tok.str()')
// fn call or type cast // fn call or type cast
if p.peek_tok.kind == .lpar { if p.peek_tok.kind == .lpar {
name := p.tok.lit mut name := p.tok.lit
if mod.len > 0 {
name = '${mod}.$name'
}
// type cast. TODO: finish // type cast. TODO: finish
// if name in table.builtin_type_names { // if name in table.builtin_type_names {
if name in p.table.type_idxs && !(name in ['stat', 'sigaction']) { if name in p.table.type_idxs && !(name in ['C.stat', 'C.sigaction']) {
// TODO handle C.stat() // TODO handle C.stat()
to_typ := p.parse_type() to_typ := p.parse_type()
p.check(.lpar) p.check(.lpar)
@ -1426,7 +1431,7 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
p.next() // C p.next() // C
p.next() // . p.next() // .
} }
name := p.check_name() mut name := p.check_name()
p.check(.lcbr) p.check(.lcbr)
mut ast_fields := []ast.Field mut ast_fields := []ast.Field
mut fields := []table.Field mut fields := []table.Field
@ -1469,9 +1474,14 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
// println('struct field $ti.name $field_name') // println('struct field $ti.name $field_name')
} }
p.check(.rcbr) p.check(.rcbr)
if is_c {
name = 'C.$name'
} else {
name = p.prepend_mod(name)
}
t := table.TypeSymbol{ t := table.TypeSymbol{
kind: .struct_ kind: .struct_
name: p.prepend_mod(name) name: name
info: table.Struct{ info: table.Struct{
fields: fields fields: fields
} }

View File

@ -89,6 +89,18 @@ pub enum Kind {
enum_ enum_
} }
[inline]
pub fn (t &TypeSymbol) enum_info() Enum {
match t.info {
Enum {
return it
}
else {
panic('TypeSymbol.enum_info(): no enum info')
}
}
}
[inline] [inline]
pub fn (t &TypeSymbol) mr_info() MultiReturn { pub fn (t &TypeSymbol) mr_info() MultiReturn {
match t.info { match t.info {