mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
native: increase support for ast.Alias
and ast.TypeOf
(#18722)
This commit is contained in:
parent
015ccc2a7f
commit
ee429bb51d
@ -112,11 +112,6 @@ fn (mut c Amd64) dec(reg Amd64Register) {
|
|||||||
c.g.println('dec ${reg}')
|
c.g.println('dec ${reg}')
|
||||||
}
|
}
|
||||||
|
|
||||||
[inline]
|
|
||||||
fn byt(n int, s int) u8 {
|
|
||||||
return u8((n >> (s * 8)) & 0xff)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (mut c Amd64) inc(reg Amd64Register) {
|
fn (mut c Amd64) inc(reg Amd64Register) {
|
||||||
c.g.write8(0x48)
|
c.g.write8(0x48)
|
||||||
c.g.write8(0xff)
|
c.g.write8(0xff)
|
||||||
@ -1009,6 +1004,7 @@ fn (mut c Amd64) push(reg Amd64Register) {
|
|||||||
}
|
}
|
||||||
c.is_16bit_aligned = !c.is_16bit_aligned
|
c.is_16bit_aligned = !c.is_16bit_aligned
|
||||||
c.g.println('push ${reg}')
|
c.g.println('push ${reg}')
|
||||||
|
c.g.stack_depth++
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Amd64) pop(reg Amd64Register) {
|
pub fn (mut c Amd64) pop(reg Amd64Register) {
|
||||||
@ -1018,6 +1014,7 @@ pub fn (mut c Amd64) pop(reg Amd64Register) {
|
|||||||
c.g.write8(0x58 + int(reg) % 8)
|
c.g.write8(0x58 + int(reg) % 8)
|
||||||
c.is_16bit_aligned = !c.is_16bit_aligned
|
c.is_16bit_aligned = !c.is_16bit_aligned
|
||||||
c.g.println('pop ${reg}')
|
c.g.println('pop ${reg}')
|
||||||
|
c.g.stack_depth--
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Amd64) sub8(reg Amd64Register, val int) {
|
pub fn (mut c Amd64) sub8(reg Amd64Register, val int) {
|
||||||
@ -2102,9 +2099,15 @@ fn (mut c Amd64) assign_right_expr(node ast.AssignStmt, i int, right ast.Expr, n
|
|||||||
ast.StructInit {
|
ast.StructInit {
|
||||||
match node.op {
|
match node.op {
|
||||||
.decl_assign {
|
.decl_assign {
|
||||||
c.g.allocate_by_type(name, right.typ)
|
dest := c.g.allocate_by_type(name, right.typ)
|
||||||
|
if right.typ.is_any_kind_of_pointer()
|
||||||
|
|| c.g.unwrap(right.typ).is_any_kind_of_pointer() {
|
||||||
|
c.g.expr(right)
|
||||||
|
c.mov_reg_to_var(LocalVar{dest, ast.u64_type_idx, name}, Amd64Register.rax)
|
||||||
|
} else {
|
||||||
c.init_struct(ident, right)
|
c.init_struct(ident, right)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
c.g.n_error('Unexpected operator `${node.op}`')
|
c.g.n_error('Unexpected operator `${node.op}`')
|
||||||
}
|
}
|
||||||
@ -2773,6 +2776,9 @@ fn (mut c Amd64) gen_left_value(node ast.Expr) {
|
|||||||
c.add(.rax, offset)
|
c.add(.rax, offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ast.StructInit, ast.ArrayInit {
|
||||||
|
c.g.expr(node)
|
||||||
|
}
|
||||||
ast.IndexExpr {} // TODO
|
ast.IndexExpr {} // TODO
|
||||||
ast.PrefixExpr {
|
ast.PrefixExpr {
|
||||||
if node.op != .mul {
|
if node.op != .mul {
|
||||||
@ -2825,23 +2831,7 @@ fn (mut c Amd64) prefix_expr(node ast.PrefixExpr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Amd64) infix_expr(node ast.InfixExpr) {
|
fn (mut c Amd64) fp_infix_expr(node ast.InfixExpr, left_type ast.Type) {
|
||||||
if node.op in [.logical_or, .and] {
|
|
||||||
c.g.expr(node.left)
|
|
||||||
label := c.g.labels.new_label()
|
|
||||||
c.cmp_zero(Amd64Register.rax)
|
|
||||||
jump_addr := c.cjmp(if node.op == .logical_or { .jne } else { .je })
|
|
||||||
c.g.labels.patches << LabelPatch{
|
|
||||||
id: label
|
|
||||||
pos: jump_addr
|
|
||||||
}
|
|
||||||
c.g.expr(node.right)
|
|
||||||
c.g.labels.addrs[label] = c.g.pos()
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
c.g.expr(node.right)
|
|
||||||
if node.left_type.is_pure_float() {
|
|
||||||
typ := node.left_type
|
|
||||||
// optimize for ast.Ident
|
// optimize for ast.Ident
|
||||||
match node.left {
|
match node.left {
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
@ -2865,7 +2855,7 @@ fn (mut c Amd64) infix_expr(node ast.InfixExpr) {
|
|||||||
c.g.println('and eax, 0x1')
|
c.g.println('and eax, 0x1')
|
||||||
}
|
}
|
||||||
.gt, .lt, .ge, .le {
|
.gt, .lt, .ge, .le {
|
||||||
c.cmp_sse(.xmm0, .xmm1, typ)
|
c.cmp_sse(.xmm0, .xmm1, left_type)
|
||||||
// TODO mov_extend_reg
|
// TODO mov_extend_reg
|
||||||
c.mov64(Amd64Register.rax, 0)
|
c.mov64(Amd64Register.rax, 0)
|
||||||
c.cset(match node.op {
|
c.cset(match node.op {
|
||||||
@ -2876,23 +2866,47 @@ fn (mut c Amd64) infix_expr(node ast.InfixExpr) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
.plus {
|
.plus {
|
||||||
c.add_sse(.xmm0, .xmm1, typ)
|
c.add_sse(.xmm0, .xmm1, left_type)
|
||||||
}
|
}
|
||||||
.minus {
|
.minus {
|
||||||
c.sub_sse(.xmm0, .xmm1, typ)
|
c.sub_sse(.xmm0, .xmm1, left_type)
|
||||||
}
|
}
|
||||||
.mul {
|
.mul {
|
||||||
c.mul_sse(.xmm0, .xmm1, typ)
|
c.mul_sse(.xmm0, .xmm1, left_type)
|
||||||
}
|
}
|
||||||
.div {
|
.div {
|
||||||
c.div_sse(.xmm0, .xmm1, typ)
|
c.div_sse(.xmm0, .xmm1, left_type)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c.g.n_error('`${node.op}` expression is not supported right now')
|
c.g.n_error('`${node.op}` expression is not supported right now')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut c Amd64) infix_expr(node ast.InfixExpr) {
|
||||||
|
if node.op in [.logical_or, .and] {
|
||||||
|
c.g.expr(node.left)
|
||||||
|
label := c.g.labels.new_label()
|
||||||
|
c.cmp_zero(Amd64Register.rax)
|
||||||
|
jump_addr := c.cjmp(if node.op == .logical_or { .jne } else { .je })
|
||||||
|
c.g.labels.patches << LabelPatch{
|
||||||
|
id: label
|
||||||
|
pos: jump_addr
|
||||||
|
}
|
||||||
|
c.g.expr(node.right)
|
||||||
|
c.g.labels.addrs[label] = c.g.pos()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.g.expr(node.right)
|
||||||
|
|
||||||
|
left_type := c.g.unwrap(node.left_type)
|
||||||
|
|
||||||
|
if left_type.is_pure_float() {
|
||||||
|
c.fp_infix_expr(node, left_type)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// optimize for ast.Ident
|
// optimize for ast.Ident
|
||||||
match node.left {
|
match node.left {
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
@ -2911,11 +2925,13 @@ fn (mut c Amd64) infix_expr(node ast.InfixExpr) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if node.left_type !in ast.integer_type_idxs && node.left_type != ast.bool_type_idx
|
|
||||||
&& c.g.table.sym(node.left_type).info !is ast.Enum && !node.left_type.is_ptr()
|
if left_type !in ast.integer_type_idxs && left_type != ast.bool_type_idx
|
||||||
&& !node.left_type.is_voidptr() {
|
&& c.g.table.sym(left_type).info !is ast.Enum && !left_type.is_any_kind_of_pointer()
|
||||||
c.g.n_error('unsupported type for `${node.op}`: ${node.left_type}')
|
&& node.left_type.is_any_kind_of_pointer() {
|
||||||
|
c.g.n_error('unsupported type for `${node.op}`: ${left_type}')
|
||||||
}
|
}
|
||||||
|
|
||||||
// left: rax, right: rdx
|
// left: rax, right: rdx
|
||||||
match node.op {
|
match node.op {
|
||||||
.eq, .ne, .gt, .lt, .ge, .le {
|
.eq, .ne, .gt, .lt, .ge, .le {
|
||||||
@ -2935,7 +2951,7 @@ fn (mut c Amd64) infix_expr(node ast.InfixExpr) {
|
|||||||
c.g.println('imul rax, rdx')
|
c.g.println('imul rax, rdx')
|
||||||
}
|
}
|
||||||
.div {
|
.div {
|
||||||
if node.left_type in ast.unsigned_integer_type_idxs {
|
if left_type in ast.unsigned_integer_type_idxs {
|
||||||
c.g.write8(0xba)
|
c.g.write8(0xba)
|
||||||
c.g.write32(0)
|
c.g.write32(0)
|
||||||
c.g.println('mov edx, 0')
|
c.g.println('mov edx, 0')
|
||||||
@ -2949,7 +2965,7 @@ fn (mut c Amd64) infix_expr(node ast.InfixExpr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.mod {
|
.mod {
|
||||||
if node.left_type in ast.unsigned_integer_type_idxs {
|
if left_type in ast.unsigned_integer_type_idxs {
|
||||||
c.g.write8(0xba)
|
c.g.write8(0xba)
|
||||||
c.g.write32(0)
|
c.g.write32(0)
|
||||||
c.g.println('mov edx, 0')
|
c.g.println('mov edx, 0')
|
||||||
@ -2986,15 +3002,9 @@ fn (mut c Amd64) infix_expr(node ast.InfixExpr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn (mut c Amd64) trap() {
|
fn (mut c Amd64) trap() {
|
||||||
// funnily works on x86 and arm64
|
|
||||||
if c.g.pref.arch == .arm64 {
|
|
||||||
c.g.write32(0xcccccccc)
|
|
||||||
} else {
|
|
||||||
c.g.write8(0xcc)
|
c.g.write8(0xcc)
|
||||||
}
|
|
||||||
c.g.println('trap')
|
c.g.println('trap')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3993,6 +4003,7 @@ fn (mut c Amd64) push_sse(reg Amd64SSERegister) {
|
|||||||
c.g.println('movsd [rsp], ${reg}')
|
c.g.println('movsd [rsp], ${reg}')
|
||||||
c.is_16bit_aligned = !c.is_16bit_aligned
|
c.is_16bit_aligned = !c.is_16bit_aligned
|
||||||
c.g.println('; push ${reg}')
|
c.g.println('; push ${reg}')
|
||||||
|
c.g.stack_depth++
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Amd64) pop_sse(reg Amd64SSERegister) {
|
fn (mut c Amd64) pop_sse(reg Amd64SSERegister) {
|
||||||
@ -4008,6 +4019,7 @@ fn (mut c Amd64) pop_sse(reg Amd64SSERegister) {
|
|||||||
c.g.println('add rsp, 0x8')
|
c.g.println('add rsp, 0x8')
|
||||||
c.is_16bit_aligned = !c.is_16bit_aligned
|
c.is_16bit_aligned = !c.is_16bit_aligned
|
||||||
c.g.println('; pop ${reg}')
|
c.g.println('; pop ${reg}')
|
||||||
|
c.g.stack_depth--
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Amd64) gen_cast_expr(expr ast.CastExpr) {
|
fn (mut c Amd64) gen_cast_expr(expr ast.CastExpr) {
|
||||||
|
@ -385,7 +385,8 @@ fn (mut c Arm64) apicall(call ApiCall) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Arm64) trap() {
|
fn (mut c Arm64) trap() {
|
||||||
panic('Arm64.trap() not implemented')
|
c.g.write32(0xcccccccc)
|
||||||
|
c.g.println('trap')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Arm64) leave() {
|
fn (mut c Arm64) leave() {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
module native
|
module native
|
||||||
|
|
||||||
import v.ast
|
import v.ast
|
||||||
|
import v.util
|
||||||
|
|
||||||
fn (mut g Gen) expr(node ast.Expr) {
|
fn (mut g Gen) expr(node ast.Expr) {
|
||||||
match node {
|
match node {
|
||||||
@ -16,54 +17,35 @@ fn (mut g Gen) expr(node ast.Expr) {
|
|||||||
g.code_gen.lea_var_to_reg(g.code_gen.main_reg(), pos)
|
g.code_gen.lea_var_to_reg(g.code_gen.main_reg(), pos)
|
||||||
}
|
}
|
||||||
ast.BoolLiteral {
|
ast.BoolLiteral {
|
||||||
g.code_gen.mov64(g.code_gen.main_reg(), if node.val {
|
g.code_gen.mov64(g.code_gen.main_reg(), int(node.val))
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
ast.CallExpr {
|
ast.CallExpr {
|
||||||
if node.name == 'C.syscall' {
|
match node.name {
|
||||||
|
'C.syscall' {
|
||||||
g.code_gen.gen_syscall(node)
|
g.code_gen.gen_syscall(node)
|
||||||
} else if node.name == 'exit' {
|
}
|
||||||
|
'exit' {
|
||||||
g.code_gen.gen_exit(node.args[0].expr)
|
g.code_gen.gen_exit(node.args[0].expr)
|
||||||
} else if node.name in ['println', 'print', 'eprintln', 'eprint'] {
|
}
|
||||||
|
'println', 'print', 'eprintln', 'eprint' {
|
||||||
expr := node.args[0].expr
|
expr := node.args[0].expr
|
||||||
typ := node.args[0].typ
|
typ := node.args[0].typ
|
||||||
g.gen_print_from_expr(expr, typ, node.name)
|
g.gen_print_from_expr(expr, typ, node.name)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
g.code_gen.call_fn(node)
|
g.code_gen.call_fn(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ast.FloatLiteral {
|
ast.FloatLiteral {
|
||||||
val := g.eval.expr(node, ast.float_literal_type_idx).float_val()
|
val := g.eval.expr(node, ast.float_literal_type_idx).float_val()
|
||||||
g.code_gen.load_fp(val)
|
g.code_gen.load_fp(val)
|
||||||
}
|
}
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
var := g.get_var_from_ident(node)
|
var := g.get_var_from_ident(node)
|
||||||
// XXX this is intel specific
|
|
||||||
match var {
|
match var {
|
||||||
LocalVar {
|
LocalVar {
|
||||||
if g.is_register_type(var.typ) {
|
g.local_var_ident(node, var)
|
||||||
g.code_gen.mov_var_to_reg(g.code_gen.main_reg(), node as ast.Ident)
|
|
||||||
} else if var.typ.is_pure_float() {
|
|
||||||
g.code_gen.load_fp_var(node as ast.Ident)
|
|
||||||
} else {
|
|
||||||
ts := g.table.sym(g.unwrap(var.typ))
|
|
||||||
match ts.info {
|
|
||||||
ast.Struct {
|
|
||||||
g.code_gen.lea_var_to_reg(g.code_gen.main_reg(), g.get_var_offset(node.name))
|
|
||||||
}
|
|
||||||
ast.Enum {
|
|
||||||
g.code_gen.mov_var_to_reg(g.code_gen.main_reg(), node as ast.Ident,
|
|
||||||
typ: ast.int_type_idx
|
|
||||||
)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
g.n_error('Unsupported variable type')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
g.n_error('Unsupported variable kind')
|
g.n_error('Unsupported variable kind')
|
||||||
@ -131,12 +113,38 @@ fn (mut g Gen) expr(node ast.Expr) {
|
|||||||
ast.ConcatExpr {
|
ast.ConcatExpr {
|
||||||
g.code_gen.gen_concat_expr(node)
|
g.code_gen.gen_concat_expr(node)
|
||||||
}
|
}
|
||||||
|
ast.TypeOf {
|
||||||
|
g.gen_typeof_expr(node, false)
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
g.n_error('expr: unhandled node type: ${node.type_name()}')
|
g.n_error('expr: unhandled node type: ${node.type_name()}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) local_var_ident(ident ast.Ident, var LocalVar) {
|
||||||
|
if g.is_register_type(var.typ) {
|
||||||
|
g.code_gen.mov_var_to_reg(g.code_gen.main_reg(), ident)
|
||||||
|
} else if g.is_fp_type(var.typ) {
|
||||||
|
g.code_gen.load_fp_var(ident)
|
||||||
|
} else {
|
||||||
|
ts := g.table.sym(g.unwrap(var.typ))
|
||||||
|
match ts.info {
|
||||||
|
ast.Struct {
|
||||||
|
g.code_gen.lea_var_to_reg(g.code_gen.main_reg(), g.get_var_offset(ident.name))
|
||||||
|
}
|
||||||
|
ast.Enum {
|
||||||
|
g.code_gen.mov_var_to_reg(g.code_gen.main_reg(), ident,
|
||||||
|
typ: ast.int_type_idx
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g.n_error('Unsupported variable type')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn (mut g Gen) condition(expr ast.Expr, neg bool) int {
|
fn (mut g Gen) condition(expr ast.Expr, neg bool) int {
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
g.code_gen.cmp_zero(g.code_gen.main_reg())
|
g.code_gen.cmp_zero(g.code_gen.main_reg())
|
||||||
@ -213,10 +221,66 @@ fn (mut g Gen) postfix_expr(node ast.PostfixExpr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) gen_typeof_expr(it ast.TypeOf, newline bool) {
|
fn (mut g Gen) fn_decl_str(info ast.FnType) string {
|
||||||
|
mut fn_str := 'fn ('
|
||||||
|
for i, arg in info.func.params {
|
||||||
|
if arg.is_mut {
|
||||||
|
fn_str += 'mut '
|
||||||
|
}
|
||||||
|
if i > 0 {
|
||||||
|
fn_str += ', '
|
||||||
|
}
|
||||||
|
fn_str += util.strip_main_name(g.table.get_type_name(arg.typ))
|
||||||
|
}
|
||||||
|
fn_str += ')'
|
||||||
|
if info.func.return_type == ast.ovoid_type {
|
||||||
|
fn_str += ' ?'
|
||||||
|
} else if info.func.return_type == ast.rvoid_type {
|
||||||
|
fn_str += ' !'
|
||||||
|
} else if info.func.return_type != ast.void_type {
|
||||||
|
x := util.strip_main_name(g.table.get_type_name(info.func.return_type))
|
||||||
|
if info.func.return_type.has_flag(.option) {
|
||||||
|
fn_str += ' ?${x}'
|
||||||
|
} else if info.func.return_type.has_flag(.result) {
|
||||||
|
fn_str += ' !${x}'
|
||||||
|
} else {
|
||||||
|
fn_str += ' ${x}'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fn_str
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) gen_typeof_expr(node ast.TypeOf, newline bool) {
|
||||||
nl := if newline { '\n' } else { '' }
|
nl := if newline { '\n' } else { '' }
|
||||||
r := g.typ(it.typ).name
|
ts := g.table.sym(node.typ)
|
||||||
g.code_gen.learel(g.code_gen.main_reg(), g.allocate_string('${r}${nl}', 3, .rel32))
|
mut str := ''
|
||||||
|
|
||||||
|
match ts.kind {
|
||||||
|
.sum_type {
|
||||||
|
g.n_error('`typeof()` is not implemented for sum types yet')
|
||||||
|
}
|
||||||
|
.array_fixed {
|
||||||
|
fixed_info := ts.info as ast.ArrayFixed
|
||||||
|
typ_name := g.table.get_type_name(fixed_info.elem_type)
|
||||||
|
str = '[${fixed_info.size}]${util.strip_main_name(typ_name)}'
|
||||||
|
}
|
||||||
|
.function {
|
||||||
|
func_info := ts.info as ast.FnType
|
||||||
|
if node.typ.is_ptr() {
|
||||||
|
str = '&'
|
||||||
|
}
|
||||||
|
str += g.fn_decl_str(func_info)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
str = util.strip_main_name(if node.typ.has_flag(.variadic) {
|
||||||
|
g.table.sym(g.table.value_type(node.typ)).name
|
||||||
|
} else {
|
||||||
|
g.table.type_to_str(node.typ)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g.code_gen.learel(g.code_gen.main_reg(), g.allocate_string('${str}${nl}', 3, .rel32))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) gen_print_from_expr(expr ast.Expr, typ ast.Type, name string) {
|
fn (mut g Gen) gen_print_from_expr(expr ast.Expr, typ ast.Type, name string) {
|
||||||
|
@ -41,6 +41,7 @@ mut:
|
|||||||
var_offset map[string]int // local var stack offset
|
var_offset map[string]int // local var stack offset
|
||||||
var_alloc_size map[string]int // local var allocation size
|
var_alloc_size map[string]int // local var allocation size
|
||||||
stack_var_pos int
|
stack_var_pos int
|
||||||
|
stack_depth int
|
||||||
debug_pos int
|
debug_pos int
|
||||||
errors []errors.Error
|
errors []errors.Error
|
||||||
warnings []errors.Warning
|
warnings []errors.Warning
|
||||||
@ -230,6 +231,11 @@ union F64I64 {
|
|||||||
i i64
|
i i64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[inline]
|
||||||
|
fn byt(n int, s int) u8 {
|
||||||
|
return u8((n >> (s * 8)) & 0xff)
|
||||||
|
}
|
||||||
|
|
||||||
fn (mut g Gen) get_var_from_ident(ident ast.Ident) IdentVar {
|
fn (mut g Gen) get_var_from_ident(ident ast.Ident) IdentVar {
|
||||||
mut obj := ident.obj
|
mut obj := ident.obj
|
||||||
if obj !in [ast.Var, ast.ConstField, ast.GlobalField, ast.AsmRegister] {
|
if obj !in [ast.Var, ast.ConstField, ast.GlobalField, ast.AsmRegister] {
|
||||||
@ -735,9 +741,15 @@ fn (mut g Gen) get_multi_return(types []ast.Type) MultiReturn {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g Gen) is_register_type(typ ast.Type) bool {
|
fn (mut g Gen) is_register_type(typ ast.Type) bool {
|
||||||
return typ.is_pure_int() || typ == ast.char_type_idx || typ.is_any_kind_of_pointer()
|
return typ.is_pure_int() || typ == ast.char_type_idx
|
||||||
|| typ.is_bool()
|
|| typ.is_any_kind_of_pointer() || typ.is_bool()
|
||||||
|
|| (g.table.sym(typ).info is ast.Alias && g.is_register_type(g.unwrap(typ)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) is_fp_type(typ ast.Type) bool {
|
||||||
|
return typ.is_pure_float()
|
||||||
|
|| (g.table.sym(typ).info is ast.Alias && g.is_fp_type(g.unwrap(typ)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) get_sizeof_ident(ident ast.Ident) int {
|
fn (mut g Gen) get_sizeof_ident(ident ast.Ident) int {
|
||||||
@ -981,12 +993,17 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
g.stack_var_pos = 0
|
g.stack_var_pos = 0
|
||||||
|
g.stack_depth = 0
|
||||||
g.register_function_address(name)
|
g.register_function_address(name)
|
||||||
g.labels = &LabelTable{}
|
g.labels = &LabelTable{}
|
||||||
g.defer_stmts.clear()
|
g.defer_stmts.clear()
|
||||||
g.return_type = node.return_type
|
g.return_type = node.return_type
|
||||||
g.code_gen.fn_decl(node)
|
g.code_gen.fn_decl(node)
|
||||||
g.patch_labels()
|
g.patch_labels()
|
||||||
|
|
||||||
|
if g.stack_depth != 0 {
|
||||||
|
g.println('^^^ stack_depth != 0 (${g.stack_depth}) !!!')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut g Gen) register_function_address(name string) {
|
pub fn (mut g Gen) register_function_address(name string) {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
test_int()
|
test_int()
|
||||||
test_fp()
|
test_fp()
|
||||||
|
test_unsafe()
|
||||||
|
test_alias(100, 9)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_int() {
|
fn test_int() {
|
||||||
@ -26,3 +28,20 @@ fn test_fp() {
|
|||||||
|
|
||||||
println(int(b))
|
println(int(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_unsafe() {
|
||||||
|
a := 10
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
b := 4
|
||||||
|
println(a + b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Integer = int
|
||||||
|
|
||||||
|
fn test_alias(a Integer, b Integer) {
|
||||||
|
e := a + b
|
||||||
|
assert e == a + b
|
||||||
|
println(e)
|
||||||
|
}
|
@ -1,2 +1,4 @@
|
|||||||
246
|
246
|
||||||
3
|
3
|
||||||
|
14
|
||||||
|
109
|
||||||
|
@ -56,6 +56,9 @@ fn struct_test() {
|
|||||||
mut f := &e
|
mut f := &e
|
||||||
f.a = 3
|
f.a = 3
|
||||||
assert e.a == 3
|
assert e.a == 3
|
||||||
|
|
||||||
|
g := &Mutable{2}
|
||||||
|
assert g.a == 2
|
||||||
}
|
}
|
||||||
|
|
||||||
type AliasedStruct = Mutable
|
type AliasedStruct = Mutable
|
||||||
|
@ -1,16 +1,86 @@
|
|||||||
|
type IntegerAlias = int
|
||||||
|
|
||||||
|
struct Test {
|
||||||
|
a int = 0
|
||||||
|
b voidptr = voidptr(0)
|
||||||
|
c &Test = unsafe { 0 }
|
||||||
|
d map[int][3]string = {}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// strings
|
||||||
a := 'string'
|
a := 'string'
|
||||||
t := typeof(a)
|
t := typeof(a)
|
||||||
println(t)
|
println(t)
|
||||||
t2 := typeof('another string')
|
t2 := typeof('another string')
|
||||||
println(t2)
|
println(t2)
|
||||||
|
|
||||||
|
// integers
|
||||||
n := 123
|
n := 123
|
||||||
t3 := typeof(n)
|
t3 := typeof(n)
|
||||||
println(t3)
|
println(t3)
|
||||||
t4 := typeof(123)
|
t4 := typeof(123)
|
||||||
println(t4)
|
println(t4)
|
||||||
// id := 'hello world'
|
test_alias(0)
|
||||||
// println(id)
|
|
||||||
|
// pointers
|
||||||
|
t5 := typeof(voidptr(0))
|
||||||
|
println(t5)
|
||||||
|
t6 := typeof(charptr(0))
|
||||||
|
println(t6)
|
||||||
|
t7 := typeof(&u8(3))
|
||||||
|
println(t7)
|
||||||
|
|
||||||
|
// functions
|
||||||
|
t8 := typeof(main)
|
||||||
|
println(t8)
|
||||||
|
t9 := typeof(test_alias)
|
||||||
|
println(t9)
|
||||||
|
t10 := typeof(return_func)
|
||||||
|
println(t10)
|
||||||
|
|
||||||
|
// arrays
|
||||||
|
t11 := typeof([]int{})
|
||||||
|
println(t11)
|
||||||
|
t12 := typeof([16]int{})
|
||||||
|
println(t12)
|
||||||
|
|
||||||
|
// maps
|
||||||
|
t13 := typeof(map[int]string)
|
||||||
|
println(t13)
|
||||||
|
t14 := typeof(map[int][2]int)
|
||||||
|
println(t14)
|
||||||
|
|
||||||
|
// options, results
|
||||||
|
t15 := typeof(result_func)
|
||||||
|
println(t15)
|
||||||
|
t16 := typeof(result_func())
|
||||||
|
println(t16)
|
||||||
|
t17 := typeof(opt_func)
|
||||||
|
println(t17)
|
||||||
|
t18 := typeof(opt_func())
|
||||||
|
println(t18)
|
||||||
|
|
||||||
|
// structs
|
||||||
|
t19 := typeof(Test{})
|
||||||
|
println(t19)
|
||||||
|
t20 := typeof(Test{}.d)
|
||||||
|
println(t20)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_alias(t IntegerAlias) {
|
||||||
|
t1 := typeof(t)
|
||||||
|
println(t1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn return_func(foo int, bar []int, baz voidptr) string {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
fn result_func() !int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn opt_func() ?int {
|
||||||
|
return 0
|
||||||
}
|
}
|
@ -2,3 +2,20 @@ string
|
|||||||
string
|
string
|
||||||
int
|
int
|
||||||
int literal
|
int literal
|
||||||
|
IntegerAlias
|
||||||
|
voidptr
|
||||||
|
charptr
|
||||||
|
&u8
|
||||||
|
fn ()
|
||||||
|
fn (IntegerAlias)
|
||||||
|
fn (int, []int, voidptr) string
|
||||||
|
[]int
|
||||||
|
[16]int
|
||||||
|
map[int]string
|
||||||
|
map[int][2]int
|
||||||
|
fn () !int
|
||||||
|
!int
|
||||||
|
fn () ?int
|
||||||
|
?int
|
||||||
|
Test
|
||||||
|
map[int][3]string
|
||||||
|
Loading…
Reference in New Issue
Block a user