checker: << check; initial #flag os support

pull/4259/head
Alexander Medvednikov 2020-04-06 02:05:08 +02:00
parent a30d292385
commit be014fcdd6
4 changed files with 31 additions and 11 deletions

View File

@ -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

View File

@ -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 {}

View File

@ -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']
)

View File

@ -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
}