cgen: use faster array_push instead of _PUSH; re-fmt cgen.v

pull/4516/head
Alexander Medvednikov 2020-04-20 03:54:35 +02:00
parent be3bd520f6
commit 19a5436118
1 changed files with 116 additions and 243 deletions

View File

@ -14,9 +14,13 @@ import term
const (
c_reserved = ['delete', 'exit', 'unix', 'error', 'calloc', 'malloc', 'free', 'panic', 'auto',
'char', 'default', 'do', 'double', 'extern', 'float', 'inline', 'int', 'long', 'register',
'restrict', 'short', 'signed', 'sizeof', 'static', 'switch', 'typedef', 'union', 'unsigned',
'void', 'volatile', 'while']
'char'
'default'
'do'
'double', 'extern', 'float', 'inline', 'int', 'long', 'register', 'restrict', 'short',
'signed'
'sizeof', 'static', 'switch', 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while'
]
)
fn foo(t token.Token) {
@ -64,7 +68,8 @@ mut:
const (
tabs = ['', '\t', '\t\t', '\t\t\t', '\t\t\t\t', '\t\t\t\t\t', '\t\t\t\t\t\t', '\t\t\t\t\t\t\t',
'\t\t\t\t\t\t\t\t']
'\t\t\t\t\t\t\t\t'
]
)
pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string {
@ -424,15 +429,12 @@ fn (var g Gen) stmt(node ast.Stmt) {
ast.ExprStmt {
g.expr(it.expr)
expr := it.expr
// no ; after an if expression }
match expr {
ast.IfExpr {
// no ; after an if expression
}
else {
if !g.inside_ternary {
ast.IfExpr {}
else { if !g.inside_ternary {
g.writeln(';')
}
}
} }
}
}
ast.FnDecl {
@ -758,9 +760,7 @@ fn (var g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
right_sym := g.table.get_type_symbol(assign_stmt.right_types[i])
var is_fixed_array_init := false
match val {
ast.ArrayInit {
is_fixed_array_init = it.is_fixed
}
ast.ArrayInit { is_fixed_array_init = it.is_fixed }
else {}
}
is_decl := assign_stmt.op == .decl_assign
@ -799,15 +799,9 @@ fn (var g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
fn (var g Gen) gen_clone_assignment(val ast.Expr, right_sym table.TypeSymbol, add_eq bool) bool {
var is_ident := false
match val {
ast.Ident {
is_ident = true
}
ast.SelectorExpr {
is_ident = true
}
else {
return false
}
ast.Ident { is_ident = true }
ast.SelectorExpr { is_ident = true }
else { return false }
}
if g.autofree && right_sym.kind == .array && is_ident {
// `arr1 = arr2` => `arr1 = arr2.clone()`
@ -1094,7 +1088,6 @@ fn (var g Gen) expr(node ast.Expr) {
ast.AnonFn {
sym := g.table.get_type_symbol(it.typ)
func := it.decl
// TODO: Fix hack and write function implementation directly to definitions
pos := g.out.len
type_name := g.typ(func.return_type)
@ -1111,11 +1104,9 @@ fn (var g Gen) expr(node ast.Expr) {
g.out.writeln('}')
g.defer_stmts = []
g.fn_decl = 0
fn_body := g.out.after(pos)
g.definitions.write(fn_body)
g.out.go_back(fn_body.len)
g.out.write('&${sym.name}_impl')
}
else {
@ -1141,7 +1132,7 @@ fn (var g Gen) typeof_expr(node ast.TypeOf) {
} else if sym.kind == .function {
info := sym.info as table.FnType
fn_info := info.func
mut repr := 'fn ('
var repr := 'fn ('
for i, arg in fn_info.args {
if i > 0 {
repr += ', '
@ -1160,12 +1151,8 @@ fn (var g Gen) typeof_expr(node ast.TypeOf) {
fn (var g Gen) enum_expr(node ast.Expr) {
match node {
ast.EnumVal {
g.write(it.val)
}
else {
g.expr(node)
}
ast.EnumVal { g.write(it.val) }
else { g.expr(node) }
}
}
@ -1261,30 +1248,14 @@ fn (var g Gen) infix_expr(node ast.InfixExpr) {
right_sym := g.table.get_type_symbol(node.right_type)
if node.left_type == table.string_type_idx && node.op != .key_in && node.op != .not_in {
fn_name := match node.op {
.plus {
'string_add('
}
.eq {
'string_eq('
}
.ne {
'string_ne('
}
.lt {
'string_lt('
}
.le {
'string_le('
}
.gt {
'string_gt('
}
.ge {
'string_ge('
}
else {
'/*node error*/'
}
.plus { 'string_add(' }
.eq { 'string_eq(' }
.ne { 'string_ne(' }
.lt { 'string_lt(' }
.le { 'string_le(' }
.gt { 'string_gt(' }
.ge { 'string_ge(' }
else { '/*node error*/' }
}
g.write(fn_name)
g.expr(node.left)
@ -1358,13 +1329,20 @@ fn (var g Gen) infix_expr(node ast.InfixExpr) {
g.write('), $tmp, $styp)')
} else {
// push a single element
/*
elem_type_str := g.typ(info.elem_type)
// g.write('array_push(&')
g.write('_PUSH(&')
g.expr(node.left)
g.write(', (')
g.expr_with_cast(node.right, node.right_type, info.elem_type)
g.write('), $tmp, $elem_type_str)')
*/
elem_type_str := g.typ(info.elem_type)
g.write('array_push(&')
g.expr(node.left)
g.write(', &($elem_type_str[]){ ')
g.expr_with_cast(node.right, node.right_type, info.elem_type)
g.write(' })')
}
} else if (node.left_type == node.right_type) && node.left_type in [table.f32_type_idx,
table.f64_type_idx] && node.op in [.eq, .ne] {
@ -1722,39 +1700,17 @@ fn (var g Gen) index_expr(node ast.IndexExpr) {
g.expr(node.index)
g.write(') ')
op := match g.assign_op {
.mult_assign {
'*'
}
.plus_assign {
'+'
}
.minus_assign {
'-'
}
.div_assign {
'/'
}
.xor_assign {
'^'
}
.mod_assign {
'%'
}
.or_assign {
'|'
}
.and_assign {
'&'
}
.left_shift_assign {
'<<'
}
.right_shift_assign {
'>>'
}
else {
''
}
.mult_assign { '*' }
.plus_assign { '+' }
.minus_assign { '-' }
.div_assign { '/' }
.xor_assign { '^' }
.mod_assign { '%' }
.or_assign { '|' }
.and_assign { '&' }
.left_shift_assign { '<<' }
.right_shift_assign { '>>' }
else { '' }
}
g.write(op)
}
@ -1953,14 +1909,16 @@ fn (var g Gen) struct_init(struct_init ast.StructInit) {
}
// var fields := []string
var inited_fields := []string // TODO this is done in checker, move to ast node
/*if struct_init.fields.len == 0 && struct_init.exprs.len > 0 {
/*
if struct_init.fields.len == 0 && struct_init.exprs.len > 0 {
// Get fields for {a,b} short syntax. Fields array wasn't set in the parser.
for f in info.fields {
fields << f.name
}
} else {
fields = struct_init.fields
}*/
}
*/
// User set fields
for i, field in struct_init.fields {
field_name := c_name(field.name)
@ -1983,7 +1941,6 @@ fn (var g Gen) struct_init(struct_init ast.StructInit) {
g.write('\t.$field_name = ')
if field.has_default_expr {
g.expr(field.default_expr)
} else {
g.write(g.type_default(field.typ))
}
@ -2469,12 +2426,8 @@ fn (var g Gen) type_of_last_statement(stmts []ast.Stmt) (string, string) {
fn (var g Gen) type_of_call_expr(node ast.Expr) string {
match node {
ast.CallExpr {
return g.typ(it.return_type)
}
else {
return typeof(node)
}
ast.CallExpr { return g.typ(it.return_type) }
else { return typeof(node) }
}
return ''
}
@ -2504,114 +2457,48 @@ fn (var g Gen) in_optimization(left ast.Expr, right ast.ArrayInit) {
fn op_to_fn_name(name string) string {
return match name {
'+' {
'_op_plus'
}
'-' {
'_op_minus'
}
'*' {
'_op_mul'
}
'/' {
'_op_div'
}
'%' {
'_op_mod'
}
else {
'bad op $name'
}
'+' { '_op_plus' }
'-' { '_op_minus' }
'*' { '_op_mul' }
'/' { '_op_div' }
'%' { '_op_mod' }
else { 'bad op $name' }
}
}
fn comp_if_to_ifdef(name string) string {
match name {
// platforms/os-es:
'windows' {
return '_WIN32'
}
'mac' {
return '__APPLE__'
}
'macos' {
return '__APPLE__'
}
'linux' {
return '__linux__'
}
'freebsd' {
return '__FreeBSD__'
}
'openbsd' {
return '__OpenBSD__'
}
'netbsd' {
return '__NetBSD__'
}
'dragonfly' {
return '__DragonFly__'
}
'msvc' {
return '_MSC_VER'
}
'android' {
return '__ANDROID__'
}
'solaris' {
return '__sun'
}
'haiku' {
return '__haiku__'
}
'linux_or_macos' {
return ''
}
'windows' { return '_WIN32' }
'mac' { return '__APPLE__' }
'macos' { return '__APPLE__' }
'linux' { return '__linux__' }
'freebsd' { return '__FreeBSD__' }
'openbsd' { return '__OpenBSD__' }
'netbsd' { return '__NetBSD__' }
'dragonfly' { return '__DragonFly__' }
'msvc' { return '_MSC_VER' }
'android' { return '__ANDROID__' }
'solaris' { return '__sun' }
'haiku' { return '__haiku__' }
'linux_or_macos' { return '' }
//
'js' {
return '_VJS'
}
'js' { return '_VJS' }
// compilers:
'tinyc' {
return '__TINYC__'
}
'clang' {
return '__clang__'
}
'mingw' {
return '__MINGW32__'
}
'msvc' {
return '_MSC_VER'
}
'tinyc' { return '__TINYC__' }
'clang' { return '__clang__' }
'mingw' { return '__MINGW32__' }
'msvc' { return '_MSC_VER' }
// other:
'debug' {
return '_VDEBUG'
}
'glibc' {
return '__GLIBC__'
}
'prealloc' {
return 'VPREALLOC'
}
'no_bounds_checking' {
return 'NO_BOUNDS_CHECK'
}
'x64' {
return 'TARGET_IS_64BIT'
}
'x32' {
return 'TARGET_IS_32BIT'
}
'little_endian' {
return 'TARGET_ORDER_IS_LITTLE'
}
'big_endian' {
return 'TARGET_ORDER_IS_BIG'
}
else {
verror('bad os ifdef name "$name"')
}
'debug' { return '_VDEBUG' }
'glibc' { return '__GLIBC__' }
'prealloc' { return 'VPREALLOC' }
'no_bounds_checking' { return 'NO_BOUNDS_CHECK' }
'x64' { return 'TARGET_IS_64BIT' }
'x32' { return 'TARGET_IS_32BIT' }
'little_endian' { return 'TARGET_ORDER_IS_LITTLE' }
'big_endian' { return 'TARGET_ORDER_IS_BIG' }
else { verror('bad os ifdef name "$name"') }
}
// verror('bad os ifdef name "$name"')
return ''
@ -2663,12 +2550,8 @@ fn (g Gen) type_default(typ table.Type) string {
}
*/
match sym.name {
'string' {
return 'tos3("")'
}
'rune' {
return '0'
}
'string' { return 'tos3("")' }
'rune' { return '0' }
else {}
}
return '{0}'
@ -2899,21 +2782,11 @@ fn (var g Gen) gen_str_for_type(sym table.TypeSymbol, styp string) {
}
g.str_types << styp
match sym.info {
table.Alias {
g.gen_str_default(sym, styp)
}
table.Array, table.ArrayFixed {
g.gen_str_for_array(it, styp)
}
table.Enum {
g.gen_str_for_enum(it, styp)
}
table.Struct {
g.gen_str_for_struct(it, styp)
}
else {
verror("could not generate string method for type \'${styp}\'")
}
table.Alias { g.gen_str_default(sym, styp) }
table.Array { g.gen_str_for_array(it, styp) }
table.Enum { g.gen_str_for_enum(it, styp) }
table.Struct { g.gen_str_for_struct(it, styp) }
else { verror("could not generate string method for type \'${styp}\'") }
}
}