From be014fcdd63cd92268e007fcd6bfdaac47d1771c Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Mon, 6 Apr 2020 02:05:08 +0200 Subject: [PATCH] checker: << check; initial #flag os support --- vlib/v/checker/checker.v | 19 ++++++++++++++----- vlib/v/gen/cgen.v | 10 ++++++---- vlib/v/parser/comptime.v | 2 +- vlib/v/parser/parser.v | 11 ++++++++++- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index af83ea368d..bddfb94aa5 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -137,16 +137,25 @@ pub fn (c mut Checker) infix_expr(infix_expr mut ast.InfixExpr) table.Type { right_type := c.expr(infix_expr.right) infix_expr.right_type = right_type right := c.table.get_type_symbol(right_type) + left := c.table.get_type_symbol(left_type) if infix_expr.op == .key_in && !(right.kind in [.array, .map, .string]) { - c.error('infix expr: `in` can only be used with array/map/string.', infix_expr.pos) + c.error('`in` can only be used with an array/map/string.', infix_expr.pos) } - if !c.table.check(right_type, left_type) { - left := c.table.get_type_symbol(left_type) - // `array << elm` - // the expressions have different types (array_x and x) + if infix_expr.op == .left_shift { + if left.kind != .array && !left.is_int() { + //c.error('<< can only be used with numbers and arrays', infix_expr.pos) + c.error('incompatible types: $left.name << $right.name', infix_expr.pos) + } if left.kind == .array && infix_expr.op == .left_shift { + // `array << elm` + // the expressions have different types (array_x and x) + if right.kind != .array && !c.table.check(c.table.value_type(left_type), right_type) { + c.error('incompatible types: $left.name << $right.name', infix_expr.pos) + } return table.void_type } + } + if !c.table.check(right_type, left_type) { // `elm in array` if right.kind in [.array, .map] && infix_expr.op == .key_in { return table.bool_type diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 21eb402aaf..d7035318d3 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -28,6 +28,7 @@ struct Gen { inits strings.Builder // contents of `void _vinit(){}` gowrappers strings.Builder // all go callsite wrappers stringliterals strings.Builder // all string literals (they depend on tos3() beeing defined + includes strings.Builder table &table.Table pref &pref.Preferences mut: @@ -69,12 +70,13 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string } // println('start cgen2') mut g := gen.Gen{ - out: strings.new_builder(100) + out: strings.new_builder(1000) typedefs: strings.new_builder(100) definitions: strings.new_builder(100) gowrappers: strings.new_builder(100) stringliterals: strings.new_builder(100) inits: strings.new_builder(100) + includes: strings.new_builder(100) table: table pref: pref fn_decl: 0 @@ -113,8 +115,8 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string } // g.finish() - return g.hashes() + g.typedefs.str() + g.definitions.str() + g.gowrappers.str() + - g.stringliterals.str() + g.out.str() + return g.hashes() + g.includes.str() + g.typedefs.str() + g.definitions.str() + + g.gowrappers.str() + g.stringliterals.str() + g.out.str() } pub fn (g Gen) hashes() string { @@ -433,7 +435,7 @@ fn (g mut Gen) stmt(node ast.Stmt) { // #include etc typ := it.val.all_before(' ') if typ in ['include', 'define'] { - g.definitions.writeln('#$it.val') + g.includes.writeln('#$it.val') } } ast.Import {} diff --git a/vlib/v/parser/comptime.v b/vlib/v/parser/comptime.v index b051215243..d51972a7f7 100644 --- a/vlib/v/parser/comptime.v +++ b/vlib/v/parser/comptime.v @@ -6,7 +6,7 @@ import ( ) const ( - supported_platforms = ['windows', 'mac', 'macos', 'linux', 'freebsd', 'openbsd', 'netbsd', + supported_platforms = ['windows', 'mac', 'macos', 'darwin', 'linux', 'freebsd', 'openbsd', 'netbsd', 'dragonfly', 'android', 'js', 'solaris', 'haiku', 'linux_or_macos'] ) diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 85b73d0ccd..2424f4a5cc 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -19,7 +19,7 @@ struct Parser { file_name string mut: tok token.Token - peek_tok token.Token // sdfsdf + peek_tok token.Token table &table.Table is_c bool inside_if bool @@ -1744,6 +1744,15 @@ fn (p mut Parser) assign_stmt() ast.Stmt { fn (p mut Parser) hash() ast.HashStmt { val := p.tok.lit p.next() + if val.starts_with('flag') { + // #flag linux -lm + words := val.split(' ') + if words.len > 1 && words[1] in supported_platforms { + if p.pref.os == .mac && words[1] == 'darwin' { + p.pref.cflags += val.after('darwin') + } + } + } return ast.HashStmt{ val: val }