mirror of
https://github.com/vlang/v.git
synced 2025-09-14 15:02:33 +03:00
add MSVC C backend support; fix live code reloading on Windows; other Windows fixes
This commit is contained in:
parent
3cf8e18cf6
commit
e25ea7f9dd
9 changed files with 1231 additions and 42 deletions
|
@ -540,6 +540,7 @@ fn (p mut Parser) struct_decl() {
|
|||
}
|
||||
println('fmt max len = $max_len nrfields=$typ.fields.len pass=$p.run')
|
||||
*/
|
||||
mut did_gen_something := false
|
||||
for p.tok != .rcbr {
|
||||
if p.tok == .key_pub {
|
||||
if is_pub {
|
||||
|
@ -604,16 +605,25 @@ fn (p mut Parser) struct_decl() {
|
|||
attr = p.check_name()
|
||||
p.check(.rsbr)
|
||||
}
|
||||
did_gen_something = true
|
||||
|
||||
typ.add_field(field_name, field_type, is_mut, attr, access_mod)
|
||||
p.fgenln('')
|
||||
}
|
||||
|
||||
if !is_ph && p.first_run() {
|
||||
p.table.register_type2(typ)
|
||||
//println('registering 1 nrfields=$typ.fields.len')
|
||||
}
|
||||
|
||||
p.check(.rcbr)
|
||||
if !is_c {
|
||||
p.gen_type('}; ')
|
||||
if p.os == .msvc && !did_gen_something {
|
||||
p.gen_type('void *____dummy_variable; };')
|
||||
p.fgenln('')
|
||||
} else {
|
||||
p.gen_type('}; ')
|
||||
}
|
||||
}
|
||||
if is_objc {
|
||||
p.gen_type('@end')
|
||||
|
@ -1891,7 +1901,10 @@ fn (p mut Parser) index_expr(typ string, fn_ph int) string {
|
|||
tmp_ok := p.get_tmp()
|
||||
if is_map {
|
||||
p.gen('$tmp')
|
||||
def := type_default(typ)
|
||||
mut def := type_default(typ)
|
||||
if p.os == .msvc && def == '{}' {
|
||||
def = '{0}'
|
||||
}
|
||||
p.cgen.insert_before('$typ $tmp = $def; bool $tmp_ok = map_get($index_expr, & $tmp);')
|
||||
}
|
||||
else if is_arr {
|
||||
|
@ -2015,6 +2028,11 @@ fn (p mut Parser) expression() string {
|
|||
}
|
||||
// 3 + 4
|
||||
else if is_num {
|
||||
if p.os == .msvc && typ == 'void*' {
|
||||
// Msvc errors on void* pointer arithmatic
|
||||
// ... So cast to byte* and then do the add
|
||||
p.cgen.set_placeholder(ph, '(byte*)')
|
||||
}
|
||||
p.gen(tok_op.str())
|
||||
}
|
||||
// Vec + Vec
|
||||
|
@ -2455,7 +2473,11 @@ fn (p mut Parser) array_init() string {
|
|||
name := p.check_name()
|
||||
if p.table.known_type(name) {
|
||||
p.cgen.resetln('')
|
||||
p.gen('{}')
|
||||
if p.os == .msvc {
|
||||
p.gen('{0}')
|
||||
} else {
|
||||
p.gen('{}')
|
||||
}
|
||||
return '[$lit]$name'
|
||||
}
|
||||
else {
|
||||
|
@ -2539,7 +2561,11 @@ fn (p mut Parser) array_init() string {
|
|||
// p.gen('$new_arr($vals.len, $vals.len, sizeof($typ), ($typ[]) $c_arr );')
|
||||
// TODO why need !first_run()?? Otherwise it goes to the very top of the out.c file
|
||||
if !p.first_run() {
|
||||
p.cgen.set_placeholder(new_arr_ph, '$new_arr($i, $i, sizeof($typ), ($typ[]) { ')
|
||||
if p.os == .msvc && i == 0 {
|
||||
p.cgen.set_placeholder(new_arr_ph, '$new_arr($i, $i, sizeof($typ), ($typ[]) {0 ')
|
||||
} else {
|
||||
p.cgen.set_placeholder(new_arr_ph, '$new_arr($i, $i, sizeof($typ), ($typ[]) { ')
|
||||
}
|
||||
}
|
||||
typ = 'array_$typ'
|
||||
p.register_array(typ)
|
||||
|
@ -2602,6 +2628,7 @@ fn (p mut Parser) struct_init(is_c_struct_init bool) string {
|
|||
no_star := typ.replace('*', '')
|
||||
p.gen('ALLOC_INIT($no_star, {')
|
||||
}
|
||||
mut did_gen_something := false
|
||||
// Loop thru all struct init keys and assign values
|
||||
// u := User{age:20, name:'bob'}
|
||||
// Remember which fields were set, so that we dont have to zero them later
|
||||
|
@ -2627,6 +2654,7 @@ fn (p mut Parser) struct_init(is_c_struct_init bool) string {
|
|||
p.gen(',')
|
||||
}
|
||||
p.fgenln('')
|
||||
did_gen_something = true
|
||||
}
|
||||
// If we already set some fields, need to prepend a comma
|
||||
if t.fields.len != inited_fields.len && inited_fields.len > 0 {
|
||||
|
@ -2650,6 +2678,7 @@ fn (p mut Parser) struct_init(is_c_struct_init bool) string {
|
|||
p.gen(',')
|
||||
}
|
||||
}
|
||||
did_gen_something = true
|
||||
}
|
||||
}
|
||||
// Point{3,4} syntax
|
||||
|
@ -2680,7 +2709,13 @@ fn (p mut Parser) struct_init(is_c_struct_init bool) string {
|
|||
if p.tok != .rcbr {
|
||||
p.error('too many fields initialized: `$typ` has $T.fields.len field(s)')
|
||||
}
|
||||
did_gen_something = true
|
||||
}
|
||||
|
||||
if p.os == .msvc && !did_gen_something {
|
||||
p.gen('0')
|
||||
}
|
||||
|
||||
p.gen('}')
|
||||
if ptr {
|
||||
p.gen(')')
|
||||
|
@ -2761,6 +2796,7 @@ fn os_name_to_ifdef(name string) string {
|
|||
case 'openbsd': return '__OpenBSD__'
|
||||
case 'netbsd': return '__NetBSD__'
|
||||
case 'dragonfly': return '__DragonFly__'
|
||||
case 'msvc': return '_MSC_VER'
|
||||
}
|
||||
panic('bad os ifdef name "$name"')
|
||||
return ''
|
||||
|
@ -2852,7 +2888,7 @@ fn (p mut Parser) chash() {
|
|||
else if hash.contains('darwin') && p.os != .mac {
|
||||
return
|
||||
}
|
||||
else if hash.contains('windows') && p.os != .windows {
|
||||
else if hash.contains('windows') && (p.os != .windows && p.os != .msvc) {
|
||||
return
|
||||
}
|
||||
// Remove "linux" etc from flag
|
||||
|
@ -2867,8 +2903,13 @@ fn (p mut Parser) chash() {
|
|||
}
|
||||
p.log('adding flag "$flag"')
|
||||
// `@VROOT/thirdparty/glad/glad.o`, make sure it exists, otherwise build it
|
||||
if has_vroot && flag.contains('.o') {
|
||||
build_thirdparty_obj_file(flag)
|
||||
if has_vroot && flag.contains('.o') {
|
||||
if p.os == .msvc {
|
||||
build_thirdparty_obj_file_with_msvc(flag)
|
||||
}
|
||||
else {
|
||||
build_thirdparty_obj_file(flag)
|
||||
}
|
||||
}
|
||||
p.table.flags << flag
|
||||
return
|
||||
|
@ -3072,7 +3113,10 @@ fn (p mut Parser) for_st() {
|
|||
p.genln('for (int l = 0; l < keys_$tmp .len; l++) {')
|
||||
p.genln(' string $i = ((string*)keys_$tmp .data)[l];')
|
||||
//p.genln(' string $i = *(string*) ( array__get(keys_$tmp, l) );')
|
||||
def := type_default(var_typ)
|
||||
mut def := type_default(typ)
|
||||
if def == '{}' {
|
||||
def = '{0}'
|
||||
}
|
||||
// TODO don't call map_get() for each key, fetch values while traversing
|
||||
// the tree (replace `map_keys()` above with `map_key_vals()`)
|
||||
p.genln('$var_typ $val = $def; map_get($tmp, $i, & $val);')
|
||||
|
@ -3262,8 +3306,15 @@ fn (p mut Parser) return_st() {
|
|||
tmp := p.get_tmp()
|
||||
ret := p.cgen.cur_line.right(ph)
|
||||
|
||||
p.cgen.resetln('$expr_type $tmp = ($expr_type)($ret);')
|
||||
p.cgen(p.cur_fn.defer_text)
|
||||
if p.os != .msvc {
|
||||
p.cgen.cur_line = '$expr_type $tmp = ($expr_type)($ret);'
|
||||
p.cgen.resetln('$expr_type $tmp = ($expr_type)($ret);')
|
||||
} else {
|
||||
// Both the return type and the expression type have already been concluded
|
||||
// to be the same - the cast is slightly pointless
|
||||
// and msvc cant do it
|
||||
p.cgen.resetln('$expr_type $tmp = ($ret);')
|
||||
}
|
||||
p.gen('return opt_ok(&$tmp, sizeof($expr_type))')
|
||||
}
|
||||
else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue