From f67fca826e3aec1c796d699edda986d213eb1a86 Mon Sep 17 00:00:00 2001 From: Joe Conigliaro Date: Sat, 29 Feb 2020 21:47:47 +1100 Subject: [PATCH] v2: fix C function & type prefixing --- vlib/v/checker/checker.v | 15 ++++++++++++++- vlib/v/parser/fn.v | 6 +----- vlib/v/parser/parse_type.v | 14 +++++++++----- vlib/v/parser/parser.v | 20 +++++++++++++++----- vlib/v/table/atype_symbols.v | 12 ++++++++++++ 5 files changed, 51 insertions(+), 16 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 297f462761..3310f88b63 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -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 { fn_name := call_expr.name 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) mut f := table.Fn{} 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 { // c.table.find_type_idx(node.enum_name) } 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') // println(info.vals) if !(node.val in info.vals) { diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 3541f40e52..8e76510b5d 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -11,11 +11,7 @@ import ( pub fn (p mut Parser) call_expr(is_c bool, mod string) ast.CallExpr { tok := p.tok name := p.check_name() - // these fns are are not defined as C functions, but are v fns and have no C prefix - // 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 } + fn_name := if is_c {'C.$name' } else if mod.len > 0 { '${mod}.$name' } else { name } p.check(.lpar) args, muts := p.call_args() node := ast.CallExpr{ diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index b0ada67f73..8488fd1319 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -90,11 +90,12 @@ pub fn (p mut Parser) parse_type() table.Type { p.check(.amp) nr_muls++ } - if p.tok.lit == 'C' { + is_c := p.tok.lit == 'C' + if is_c { p.next() 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 { typ = table.type_to_optional(typ) } @@ -104,10 +105,13 @@ pub fn (p mut Parser) parse_type() table.Type { 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 + if is_c { + name = 'C.$name' + } // `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.known_import(name) { 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') return table.new_type(idx) } - } + } } } } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index b01cf9c103..aa68f131ab 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -555,7 +555,9 @@ pub fn (p mut Parser) name_expr() ast.Expr { return node } 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 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()') // fn call or type cast 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 // 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() to_typ := p.parse_type() p.check(.lpar) @@ -1426,7 +1431,7 @@ fn (p mut Parser) struct_decl() ast.StructDecl { p.next() // C p.next() // . } - name := p.check_name() + mut name := p.check_name() p.check(.lcbr) mut ast_fields := []ast.Field mut fields := []table.Field @@ -1469,9 +1474,14 @@ fn (p mut Parser) struct_decl() ast.StructDecl { // println('struct field $ti.name $field_name') } p.check(.rcbr) + if is_c { + name = 'C.$name' + } else { + name = p.prepend_mod(name) + } t := table.TypeSymbol{ kind: .struct_ - name: p.prepend_mod(name) + name: name info: table.Struct{ fields: fields } diff --git a/vlib/v/table/atype_symbols.v b/vlib/v/table/atype_symbols.v index 7074d3b2ad..556e58a57f 100644 --- a/vlib/v/table/atype_symbols.v +++ b/vlib/v/table/atype_symbols.v @@ -89,6 +89,18 @@ pub enum Kind { enum_ } +[inline] +pub fn (t &TypeSymbol) enum_info() Enum { + match t.info { + Enum { + return it + } + else { + panic('TypeSymbol.enum_info(): no enum info') + } + } +} + [inline] pub fn (t &TypeSymbol) mr_info() MultiReturn { match t.info {