mirror of
https://github.com/vlang/v.git
synced 2025-09-08 14:51:53 -04:00
native: support C constants (#24660)
This commit is contained in:
parent
c61dda3425
commit
f5bf1b591e
@ -311,6 +311,9 @@ fn (mut c Amd64) cmp_var_reg(var Var, reg Register, config VarConfig) {
|
||||
// TODO
|
||||
// g.cmp()
|
||||
}
|
||||
ExternVar {
|
||||
c.cmp_var_reg(var_object as ExternVar, reg, config)
|
||||
}
|
||||
}
|
||||
}
|
||||
LocalVar {
|
||||
@ -330,6 +333,9 @@ fn (mut c Amd64) cmp_var_reg(var Var, reg Register, config VarConfig) {
|
||||
GlobalVar {
|
||||
// TODO
|
||||
}
|
||||
ExternVar {
|
||||
c.g.n_error('${@LOCATION} unsupported var type ${var}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,6 +354,9 @@ fn (mut c Amd64) cmp_var(var Var, val i32, config VarConfig) {
|
||||
// TODO
|
||||
// g.cmp()
|
||||
}
|
||||
ExternVar {
|
||||
c.cmp_var(var_object as ExternVar, val, config)
|
||||
}
|
||||
}
|
||||
}
|
||||
LocalVar {
|
||||
@ -367,6 +376,9 @@ fn (mut c Amd64) cmp_var(var Var, val i32, config VarConfig) {
|
||||
GlobalVar {
|
||||
// TODO
|
||||
}
|
||||
ExternVar {
|
||||
c.g.n_error('${@LOCATION} unsupported var type ${var}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -386,6 +398,9 @@ fn (mut c Amd64) dec_var(var Var, config VarConfig) {
|
||||
// TODO
|
||||
// g.dec()
|
||||
}
|
||||
ExternVar {
|
||||
c.dec_var(var_object as ExternVar, config)
|
||||
}
|
||||
}
|
||||
}
|
||||
LocalVar {
|
||||
@ -405,6 +420,9 @@ fn (mut c Amd64) dec_var(var Var, config VarConfig) {
|
||||
GlobalVar {
|
||||
// TODO
|
||||
}
|
||||
ExternVar {
|
||||
c.g.n_error('${@LOCATION} unsupported var type ${var}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -425,6 +443,9 @@ fn (mut c Amd64) inc_var(var Var, config VarConfig) {
|
||||
// TODO
|
||||
// g.inc()
|
||||
}
|
||||
ExternVar {
|
||||
c.inc_var(var_object as ExternVar, config)
|
||||
}
|
||||
}
|
||||
}
|
||||
LocalVar {
|
||||
@ -468,6 +489,9 @@ fn (mut c Amd64) inc_var(var Var, config VarConfig) {
|
||||
c.g.n_error('${@LOCATION} Global variables incrementation is not supported yet')
|
||||
// TODO
|
||||
}
|
||||
ExternVar {
|
||||
c.g.n_error('${@LOCATION} unsupported var type ${var}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -662,6 +686,9 @@ fn (mut c Amd64) mov_reg_to_var(var Var, r Register, config VarConfig) {
|
||||
// TODO
|
||||
c.g.n_error('${@LOCATION} unsupported Ident Register')
|
||||
}
|
||||
ExternVar {
|
||||
c.mov_reg_to_var(var_object as ExternVar, reg, config)
|
||||
}
|
||||
}
|
||||
}
|
||||
LocalVar {
|
||||
@ -743,6 +770,9 @@ fn (mut c Amd64) mov_reg_to_var(var Var, r Register, config VarConfig) {
|
||||
// TODO
|
||||
c.g.n_error('${@LOCATION} Unsupported GlobalVar')
|
||||
}
|
||||
ExternVar {
|
||||
c.g.n_error('${@LOCATION} unsupported var type ${var}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -760,6 +790,9 @@ fn (mut c Amd64) mov_int_to_var(var Var, integer i32, config VarConfig) {
|
||||
Register {
|
||||
// TODO
|
||||
}
|
||||
ExternVar {
|
||||
c.mov_int_to_var(var_object as ExternVar, integer, config)
|
||||
}
|
||||
}
|
||||
}
|
||||
LocalVar {
|
||||
@ -822,6 +855,9 @@ fn (mut c Amd64) mov_int_to_var(var Var, integer i32, config VarConfig) {
|
||||
GlobalVar {
|
||||
// TODO
|
||||
}
|
||||
ExternVar {
|
||||
c.g.n_error('${@LOCATION} unsupported var type ${var}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -868,6 +904,9 @@ fn (mut c Amd64) mov_var_to_reg(reg Register, var Var, config VarConfig) {
|
||||
Register {
|
||||
// TODO
|
||||
}
|
||||
ExternVar {
|
||||
c.mov_var_to_reg(reg, var_object as ExternVar, config)
|
||||
}
|
||||
}
|
||||
}
|
||||
LocalVar {
|
||||
@ -933,6 +972,9 @@ fn (mut c Amd64) mov_var_to_reg(reg Register, var Var, config VarConfig) {
|
||||
GlobalVar {
|
||||
c.g.n_error('${@LOCATION} Unsupported GlobalVar')
|
||||
}
|
||||
ExternVar {
|
||||
c.g.n_error('${@LOCATION} unsupported var type ${var}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2077,19 +2119,34 @@ fn (mut c Amd64) assign_var(var IdentVar, raw_type ast.Type) {
|
||||
size := c.g.get_type_size(typ)
|
||||
if typ.is_pure_float() {
|
||||
match var {
|
||||
LocalVar { c.mov_ssereg_to_var(var as LocalVar, .xmm0) }
|
||||
GlobalVar { c.mov_ssereg_to_var(var as GlobalVar, .xmm0) }
|
||||
LocalVar {
|
||||
c.mov_ssereg_to_var(var as LocalVar, .xmm0)
|
||||
}
|
||||
GlobalVar {
|
||||
c.mov_ssereg_to_var(var as GlobalVar, .xmm0)
|
||||
}
|
||||
// Amd64Register { c.g.mov_ssereg(var as Amd64Register, .xmm0) }
|
||||
else {}
|
||||
else {
|
||||
c.g.n_error('${@LOCATION} unsupported var type ${var}')
|
||||
}
|
||||
}
|
||||
} else if info is ast.Struct && !typ.is_any_kind_of_pointer()
|
||||
&& !raw_type.is_any_kind_of_pointer() {
|
||||
c.assign_struct_var(var, typ, size)
|
||||
} else if int(size) in [1, 2, 4, 8] {
|
||||
match var {
|
||||
LocalVar { c.mov_reg_to_var(var as LocalVar, Amd64Register.rax) }
|
||||
GlobalVar { c.mov_reg_to_var(var as GlobalVar, Amd64Register.rax) }
|
||||
Register { c.mov_reg(var as Amd64Register, Amd64Register.rax) }
|
||||
LocalVar {
|
||||
c.mov_reg_to_var(var as LocalVar, Amd64Register.rax)
|
||||
}
|
||||
GlobalVar {
|
||||
c.mov_reg_to_var(var as GlobalVar, Amd64Register.rax)
|
||||
}
|
||||
Register {
|
||||
c.mov_reg(var as Amd64Register, Amd64Register.rax)
|
||||
}
|
||||
ExternVar {
|
||||
c.mov_reg_to_var(var as ExternVar, Amd64Register.rax)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
c.g.n_error('${@LOCATION} error assigning type ${typ} with size ${size}: ${info}')
|
||||
@ -2121,6 +2178,12 @@ fn (mut c Amd64) assign_ident_int_lit(node ast.AssignStmt, i i32, int_lit ast.In
|
||||
c.div_reg(.rax, .rdx)
|
||||
c.mov_reg_to_var(left, Amd64Register.rax)
|
||||
}
|
||||
.mod_assign {
|
||||
c.mov_var_to_reg(Amd64Register.rax, left)
|
||||
c.mov64(Amd64Register.rdx, i64(int_lit.val.int()))
|
||||
c.mod_reg(.rax, .rdx)
|
||||
c.mov_reg_to_var(left, Amd64Register.rax)
|
||||
}
|
||||
.decl_assign {
|
||||
c.allocate_var(left.name, 8, i64(int_lit.val.int()))
|
||||
}
|
||||
@ -2241,11 +2304,19 @@ fn (mut c Amd64) assign_ident_right_expr(node ast.AssignStmt, i i32, right ast.E
|
||||
val := enum_info.fields[right.val] or {
|
||||
c.g.n_error('${@LOCATION} enum field not found ${right.val}')
|
||||
}
|
||||
if node.op == .decl_assign {
|
||||
c.allocate_var(ident.name, enum_info.size, val)
|
||||
} else {
|
||||
c.mov64(Amd64Register.rax, val)
|
||||
c.mov_reg_to_var(ident, Amd64Register.rax)
|
||||
match val {
|
||||
Number {
|
||||
if node.op == .decl_assign {
|
||||
c.allocate_var(ident.name, enum_info.size, val)
|
||||
} else {
|
||||
c.mov64(Amd64Register.rax, val)
|
||||
c.mov_reg_to_var(ident, Amd64Register.rax)
|
||||
}
|
||||
}
|
||||
ast.Expr {
|
||||
c.g.expr(val)
|
||||
c.mov_reg_to_var(ident, Amd64Register.rax)
|
||||
}
|
||||
}
|
||||
}
|
||||
ast.FloatLiteral {
|
||||
@ -2777,14 +2848,35 @@ fn (mut c Amd64) assign_stmt(node ast.AssignStmt) {
|
||||
c.pop(.rdx) // effective address of left expr
|
||||
c.gen_type_promotion(node.right_types[0], var_type)
|
||||
|
||||
size := match c.g.get_type_size(var_type) {
|
||||
1 { Size._8 }
|
||||
2 { Size._16 }
|
||||
4 { Size._32 }
|
||||
else { Size._64 }
|
||||
}
|
||||
match node.op {
|
||||
.decl_assign, .assign {
|
||||
c.mov_store(.rdx, .rax, match c.g.get_type_size(var_type) {
|
||||
1 { ._8 }
|
||||
2 { ._16 }
|
||||
4 { ._32 }
|
||||
else { ._64 }
|
||||
})
|
||||
c.mov_store(.rdx, .rax, size)
|
||||
}
|
||||
.plus_assign {
|
||||
c.mov_deref(Amd64Register.rcx, Amd64Register.rdx, var_type)
|
||||
c.add_reg(.rax, .rcx)
|
||||
c.mov_store(.rdx, .rax, size)
|
||||
}
|
||||
.minus_assign {
|
||||
c.mov_deref(Amd64Register.rcx, Amd64Register.rdx, var_type)
|
||||
c.sub_reg(.rax, .rcx)
|
||||
c.mov_store(.rdx, .rax, size)
|
||||
}
|
||||
.and_assign {
|
||||
c.mov_deref(Amd64Register.rcx, Amd64Register.rdx, var_type)
|
||||
c.bitand_reg(.rax, .rcx)
|
||||
c.mov_store(.rdx, .rax, size)
|
||||
}
|
||||
.mod_assign {
|
||||
c.mov_deref(Amd64Register.rcx, Amd64Register.rdx, var_type)
|
||||
c.mod_reg(.rax, .rcx)
|
||||
c.mov_store(.rdx, .rax, size)
|
||||
}
|
||||
else {
|
||||
c.g.n_error('${@LOCATION} Unsupported assign instruction (${node.op})')
|
||||
@ -3676,6 +3768,9 @@ fn (mut c Amd64) init_struct(var Var, init ast.StructInit) {
|
||||
// TODO
|
||||
// c.g.cmp()
|
||||
}
|
||||
ExternVar {
|
||||
c.init_struct(var_object as ExternVar, init)
|
||||
}
|
||||
}
|
||||
}
|
||||
LocalVar {
|
||||
@ -3718,6 +3813,9 @@ fn (mut c Amd64) init_struct(var Var, init ast.StructInit) {
|
||||
GlobalVar {
|
||||
c.g.n_error('${@LOCATION} GlobalVar not implemented for ast.StructInit')
|
||||
}
|
||||
ExternVar {
|
||||
c.g.n_error('${@LOCATION} unsupported var type ${var}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3766,6 +3864,9 @@ fn (mut c Amd64) init_array(var Var, node ast.ArrayInit) {
|
||||
// TODO
|
||||
// c.g.cmp()
|
||||
}
|
||||
ExternVar {
|
||||
c.init_array(var_object as ExternVar, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
LocalVar {
|
||||
@ -3779,6 +3880,9 @@ fn (mut c Amd64) init_array(var Var, node ast.ArrayInit) {
|
||||
GlobalVar {
|
||||
c.g.n_error('${@LOCATION} GlobalVar not implemented for ast.ArrayInit')
|
||||
}
|
||||
ExternVar {
|
||||
c.g.n_error('${@LOCATION} unsupported var type ${var}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4075,6 +4179,9 @@ fn (mut c Amd64) mov_ssereg_to_var(var Var, reg Amd64SSERegister, config VarConf
|
||||
c.mov_ssereg_to_var(var_object as GlobalVar, reg, config)
|
||||
}
|
||||
Register {}
|
||||
ExternVar {
|
||||
c.mov_ssereg_to_var(var_object as ExternVar, reg, config)
|
||||
}
|
||||
}
|
||||
}
|
||||
LocalVar {
|
||||
@ -4100,6 +4207,9 @@ fn (mut c Amd64) mov_ssereg_to_var(var Var, reg Amd64SSERegister, config VarConf
|
||||
GlobalVar {
|
||||
// TODO
|
||||
}
|
||||
ExternVar {
|
||||
c.g.n_error('${@LOCATION} unsupported var type ${var}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4119,6 +4229,9 @@ fn (mut c Amd64) mov_var_to_ssereg(reg Amd64SSERegister, var Var, config VarConf
|
||||
c.mov_var_to_ssereg(reg, var_object as GlobalVar, config)
|
||||
}
|
||||
Register {}
|
||||
ExternVar {
|
||||
c.mov_var_to_ssereg(reg, var_object as ExternVar, config)
|
||||
}
|
||||
}
|
||||
}
|
||||
LocalVar {
|
||||
@ -4144,6 +4257,9 @@ fn (mut c Amd64) mov_var_to_ssereg(reg Amd64SSERegister, var Var, config VarConf
|
||||
GlobalVar {
|
||||
// TODO
|
||||
}
|
||||
ExternVar {
|
||||
c.g.n_error('${@LOCATION} unsupported var type ${var}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,36 @@ already compiling functions:
|
||||
|
||||
// false: whitelist function
|
||||
// true: blacklist function
|
||||
const whitelist = {
|
||||
const blacklist = {
|
||||
'main.main': false
|
||||
'c_error_number_str': false
|
||||
'exit': false
|
||||
'gc_is_enabled': false
|
||||
'int_max': false
|
||||
'int_min': false
|
||||
'flush_stdout': false
|
||||
'flush_stderr': false
|
||||
'print_character': true
|
||||
'u8.is_alnum': false
|
||||
'u8.is_bin_digit': false
|
||||
'u8.is_capital': false
|
||||
'u8.is_digit': false
|
||||
'u8.is_hex_digit': false
|
||||
'u8.is_letter': false
|
||||
'u8.is_oct_digit': false
|
||||
'u8.is_space': false
|
||||
'string.is_capital': false
|
||||
'string.is_ascii': false
|
||||
'string.is_identifier': false
|
||||
'string.is_blank': false
|
||||
'string.indent_width': false
|
||||
'string.index_u8': false
|
||||
'string.last_index': true
|
||||
'string.last_index_u8': false
|
||||
'string.contains_u8': false
|
||||
}
|
||||
|
||||
const windows_blacklist = {
|
||||
'main.main': false
|
||||
'c_error_number_str': false
|
||||
'exit': false
|
||||
@ -55,5 +84,9 @@ const whitelist = {
|
||||
}
|
||||
|
||||
fn (g &Gen) is_blacklisted(name string, is_builtin bool) bool {
|
||||
return whitelist[name] or { is_builtin }
|
||||
if g.pref.os == .windows {
|
||||
return windows_blacklist[name] or { is_builtin }
|
||||
} else {
|
||||
return blacklist[name] or { is_builtin }
|
||||
}
|
||||
}
|
||||
|
@ -614,7 +614,7 @@ fn (mut g Gen) gen_section_data(sections []Section) {
|
||||
|
||||
for rela in data {
|
||||
g.write64(rela.offset)
|
||||
g.fn_addr[rela.name] = rela.offset
|
||||
g.fn_addr[rela.name] = rela.offset // that's wierd it's the call offset, not the fn
|
||||
g.fn_names << rela.name
|
||||
g.write64(rela.info)
|
||||
g.write64(rela.addend)
|
||||
@ -686,7 +686,7 @@ pub fn (mut g Gen) symtab_get_index(symbols []SymbolTableSection, name string) i
|
||||
return i32(i)
|
||||
}
|
||||
}
|
||||
return 0
|
||||
panic('sym not found')
|
||||
}
|
||||
|
||||
pub fn (mut g Gen) generate_linkable_elf_header() {
|
||||
@ -847,6 +847,10 @@ pub fn (mut g Gen) gen_rela_section() {
|
||||
relocations << g.create_rela_section(symbol, call_pos - g.code_start_pos + 2,
|
||||
g.symtab_get_index(g.symbol_table, symbol[2..]), elf_r_amd64_gotpcrelx, -4)
|
||||
}
|
||||
for var_pos, symbol in g.extern_vars {
|
||||
relocations << g.create_rela_section(symbol, var_pos - g.code_start_pos + 2, g.symtab_get_index(g.symbol_table,
|
||||
symbol[2..]), elf_r_amd64_64, 0)
|
||||
}
|
||||
g.elf_rela_section.data = relocations
|
||||
g.gen_section_data([g.elf_rela_section])
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ module native
|
||||
|
||||
import v.ast
|
||||
import v.util
|
||||
import v.errors
|
||||
|
||||
fn (mut g Gen) expr(node ast.Expr) {
|
||||
match node {
|
||||
@ -47,6 +48,9 @@ fn (mut g Gen) expr(node ast.Expr) {
|
||||
LocalVar {
|
||||
g.local_var_ident(node, var)
|
||||
}
|
||||
ExternVar {
|
||||
g.extern_var_ident(var)
|
||||
}
|
||||
else {
|
||||
g.n_error('${@LOCATION} Unsupported variable kind')
|
||||
}
|
||||
@ -115,7 +119,14 @@ fn (mut g Gen) expr(node ast.Expr) {
|
||||
val := g.enum_vals[type_name].fields[node.val] or {
|
||||
g.n_error('${@LOCATION} enum field not found ${node.val}')
|
||||
}
|
||||
g.code_gen.mov64(g.code_gen.main_reg(), val)
|
||||
match val {
|
||||
Number {
|
||||
g.code_gen.mov64(g.code_gen.main_reg(), val)
|
||||
}
|
||||
ast.Expr {
|
||||
g.expr(val)
|
||||
}
|
||||
}
|
||||
}
|
||||
ast.UnsafeExpr {
|
||||
g.expr(node.expr)
|
||||
@ -148,7 +159,12 @@ fn (mut g Gen) expr(node ast.Expr) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
g.n_error('${@LOCATION} expr: unhandled node type: ${node.type_name()}')
|
||||
util.show_compiler_message('error', errors.CompilerMessage{
|
||||
message: 'detail'
|
||||
file_path: g.current_file.path
|
||||
pos: node.pos()
|
||||
})
|
||||
g.n_error('${@LOCATION} expr: unhandled node type: ${node.type_name()} ${node}')
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -174,6 +190,17 @@ fn (mut g Gen) local_var_ident(ident ast.Ident, var LocalVar) {
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) extern_var_ident(var ExternVar) {
|
||||
if g.pref.os == .linux {
|
||||
main_reg := g.code_gen.main_reg()
|
||||
g.extern_vars[g.pos()] = var.name
|
||||
g.code_gen.mov64(main_reg, Number(i64(0)))
|
||||
g.code_gen.mov_deref(main_reg, main_reg, ast.u64_type_idx)
|
||||
} else {
|
||||
g.n_error('${@LOCATION} unsupported os for ${var}')
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) condition(expr ast.Expr, neg bool) i32 {
|
||||
g.println('; condition cjmp if ${neg}:')
|
||||
g.expr(expr)
|
||||
|
@ -35,6 +35,7 @@ mut:
|
||||
extern_symbols []string
|
||||
linker_include_paths []string
|
||||
linker_libs []string
|
||||
extern_vars map[i64]string
|
||||
extern_fn_calls map[i64]string
|
||||
fn_addr map[string]i64
|
||||
fn_names []string
|
||||
@ -211,9 +212,11 @@ type Number = u64 | i64
|
||||
struct Enum {
|
||||
size i32 // size of the type of the enum in bytes
|
||||
mut:
|
||||
fields map[string]Number
|
||||
fields map[string]EnumVal
|
||||
}
|
||||
|
||||
type EnumVal = Number | ast.Expr
|
||||
|
||||
struct MultiReturn {
|
||||
mut:
|
||||
offsets []i32
|
||||
@ -235,6 +238,11 @@ struct LocalVar {
|
||||
name string
|
||||
}
|
||||
|
||||
struct ExternVar {
|
||||
typ ast.Type
|
||||
name string
|
||||
}
|
||||
|
||||
struct GlobalVar {}
|
||||
|
||||
@[params]
|
||||
@ -244,9 +252,9 @@ pub:
|
||||
typ ast.Type // type of the value you want to process e.g. struct fields.
|
||||
}
|
||||
|
||||
type Var = GlobalVar | LocalVar | ast.Ident
|
||||
type Var = GlobalVar | ExternVar | LocalVar | ast.Ident
|
||||
|
||||
type IdentVar = GlobalVar | LocalVar | Register
|
||||
type IdentVar = GlobalVar | ExternVar | LocalVar | Register
|
||||
|
||||
enum JumpOp {
|
||||
je
|
||||
@ -270,6 +278,9 @@ fn byt(n i32, s i32) u8 {
|
||||
}
|
||||
|
||||
fn (mut g Gen) get_var_from_ident(ident ast.Ident) IdentVar {
|
||||
if ident.name in g.extern_symbols {
|
||||
return ExternVar{ident.info.typ, ident.name}
|
||||
}
|
||||
mut obj := ident.obj
|
||||
if obj !in [ast.Var, ast.ConstField, ast.GlobalField, ast.AsmRegister] {
|
||||
obj = ident.scope.find(ident.name) or {
|
||||
@ -302,6 +313,9 @@ fn (mut g Gen) get_type_from_var(var Var) ast.Type {
|
||||
GlobalVar {
|
||||
g.n_error('${@LOCATION} cannot get type from GlobalVar yet')
|
||||
}
|
||||
else {
|
||||
g.n_error('${@LOCATION} unsupported var type ${var}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -548,22 +562,33 @@ pub fn (mut g Gen) calculate_enum_fields() {
|
||||
size: i32(enum_size)
|
||||
}
|
||||
mut value := Number(if decl.is_flag { i64(1) } else { i64(0) })
|
||||
mut has_expr := false
|
||||
for field in decl.fields {
|
||||
if field.has_expr {
|
||||
str_val := g.eval.expr(field.expr, ast.int_type_idx).string()
|
||||
if str_val.len >= 0 && str_val[0] == `-` {
|
||||
value = str_val.i64()
|
||||
if field.expr.is_literal() { // does not depend on other declarations (C compile time csts)
|
||||
str_val := g.eval.expr(field.expr, ast.int_type_idx).string()
|
||||
if str_val.len >= 0 && str_val[0] == `-` {
|
||||
value = str_val.i64()
|
||||
} else {
|
||||
value = str_val.u64()
|
||||
}
|
||||
} else {
|
||||
value = str_val.u64()
|
||||
enum_vals.fields[field.name] = field.expr
|
||||
has_expr = true
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
if has_expr {
|
||||
g.n_error('${@LOCATION} unsupported auto incr after C consts')
|
||||
}
|
||||
}
|
||||
match value {
|
||||
// Dereferences the sumtype (it would get assigned by address and messed up)
|
||||
i64 {
|
||||
enum_vals.fields[field.name] = value as i64
|
||||
enum_vals.fields[field.name] = Number(value as i64)
|
||||
}
|
||||
u64 {
|
||||
enum_vals.fields[field.name] = value as u64
|
||||
enum_vals.fields[field.name] = Number(value as u64)
|
||||
}
|
||||
}
|
||||
if decl.is_flag {
|
||||
|
@ -5,6 +5,7 @@ module native
|
||||
|
||||
import v.ast
|
||||
import v.util
|
||||
import v.errors
|
||||
|
||||
fn C.strtol(str &char, endptr &&char, base i32) i32
|
||||
|
||||
@ -76,9 +77,13 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||
}
|
||||
|
||||
match node.kind {
|
||||
'include', 'preinclude', 'postinclude', 'define', 'insert' {
|
||||
g.v_error('#${node.kind} is not supported with the native backend',
|
||||
node.pos)
|
||||
'include' {}
|
||||
'preinclude', 'postinclude', 'define', 'insert' {
|
||||
util.show_compiler_message('notice', errors.CompilerMessage{
|
||||
message: '#${node.kind} is not supported with the native backend'
|
||||
file_path: node.source_file
|
||||
pos: node.pos
|
||||
})
|
||||
}
|
||||
'flag' {
|
||||
// do nothing; flags are already handled when dispatching extern dependencies
|
||||
|
@ -3,6 +3,26 @@ fn main() {
|
||||
test_fp()
|
||||
test_unsafe()
|
||||
test_alias(100, 9)
|
||||
test_plus_assign()
|
||||
test_minus_assign()
|
||||
}
|
||||
|
||||
fn test_minus_assign() {
|
||||
mut a := 3
|
||||
a -= 3
|
||||
assert a == 0
|
||||
n := 2300
|
||||
a -= n
|
||||
assert a == -2300
|
||||
}
|
||||
|
||||
fn test_plus_assign() {
|
||||
mut a := 3
|
||||
a += 3
|
||||
assert a == 6
|
||||
n := 2300
|
||||
a += n
|
||||
assert a == 2306
|
||||
}
|
||||
|
||||
fn test_int() {
|
||||
|
@ -127,10 +127,6 @@ println(f64_max(-32.32, 32.32))
|
||||
println(f64_min(32.32, -32.32))
|
||||
println(f64_min(-32.32, 32.32))
|
||||
*/
|
||||
/* uncomment when C variables are working like C.stdout
|
||||
flush_stderr()
|
||||
flush_stdout()
|
||||
*/
|
||||
|
||||
gc_is_enabled() // not yet enabled so only calling it
|
||||
|
||||
@ -139,7 +135,7 @@ println(int_max(-32, 32))
|
||||
println(int_min(32, -32))
|
||||
println(int_min(-32, 32))
|
||||
|
||||
// print_character(`a`) enable when C vars will work
|
||||
//print_character(`a`) enable when C vars will work
|
||||
|
||||
// assert u8(`a`).ascii_str() == 'a' when ptr index will work
|
||||
// assert u8(`b`).ascii_str() != 'a'
|
||||
|
@ -16,6 +16,13 @@ fn test_for_c_in_string() {
|
||||
}
|
||||
}
|
||||
|
||||
fn test_c_extern_vars() {
|
||||
C.fprintf(C.stdout, 'abc'.str, 3)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test_for_c_in_string()
|
||||
test_c_extern_vars()
|
||||
flush_stderr()
|
||||
flush_stdout()
|
||||
}
|
||||
|
@ -4,3 +4,4 @@
|
||||
98
|
||||
2
|
||||
99
|
||||
abc
|
||||
|
Loading…
x
Reference in New Issue
Block a user