parser: fix prefix precedence
parent
c00ec77737
commit
eb78396307
|
@ -29,6 +29,8 @@ fn test_float_equal_operator() {
|
||||||
assert a.gtbit(1)
|
assert a.gtbit(1)
|
||||||
assert a >= 1
|
assert a >= 1
|
||||||
assert a.gebit(1)
|
assert a.gebit(1)
|
||||||
|
assert -1 == 1 * -1
|
||||||
|
assert -1.0 == 1.0 * -1.0
|
||||||
|
|
||||||
a = f64(1)
|
a = f64(1)
|
||||||
a += 0.000001
|
a += 0.000001
|
||||||
|
|
|
@ -117,7 +117,7 @@ pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !found_field {
|
if !found_field {
|
||||||
c.error('struct init: no such field `$field_name` for struct `$typ_sym.name`',
|
c.error('struct init: no such field `$field_name` for struct `$typ_sym.name`',
|
||||||
struct_init.pos)
|
struct_init.pos)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type {
|
||||||
expr_type_sym := c.table.get_type_symbol(expr_type)
|
expr_type_sym := c.table.get_type_symbol(expr_type)
|
||||||
field_type_sym := c.table.get_type_symbol(field.typ)
|
field_type_sym := c.table.get_type_symbol(field.typ)
|
||||||
if !c.table.check(expr_type, field.typ) {
|
if !c.table.check(expr_type, field.typ) {
|
||||||
c.error('cannot assign `$expr_type_sym.name` as `$field_type_sym.name` for field `$field.name`',
|
c.error('cannot assign `$expr_type_sym.name` as `$field_type_sym.name` for field `$field.name`',
|
||||||
struct_init.pos)
|
struct_init.pos)
|
||||||
}
|
}
|
||||||
struct_init.expr_types << expr_type
|
struct_init.expr_types << expr_type
|
||||||
|
@ -139,7 +139,7 @@ pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if table.type_is_ptr(field.typ) {
|
if table.type_is_ptr(field.typ) {
|
||||||
c.warn('reference field `${typ_sym.name}.${field.name}` must be initialized',
|
c.warn('reference field `${typ_sym.name}.${field.name}` must be initialized',
|
||||||
struct_init.pos)
|
struct_init.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,7 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type {
|
||||||
left_type_sym := c.table.get_type_symbol(left_type)
|
left_type_sym := c.table.get_type_symbol(left_type)
|
||||||
method_name := call_expr.name
|
method_name := call_expr.name
|
||||||
// TODO: remove this for actual methods, use only for compiler magic
|
// TODO: remove this for actual methods, use only for compiler magic
|
||||||
if left_type_sym.kind == .array && method_name in ['filter', 'clone', 'repeat', 'reverse',
|
if left_type_sym.kind == .array && method_name in ['filter', 'clone', 'repeat', 'reverse',
|
||||||
'map', 'slice'] {
|
'map', 'slice'] {
|
||||||
if method_name in ['filter', 'map'] {
|
if method_name in ['filter', 'map'] {
|
||||||
array_info := left_type_sym.info as table.Array
|
array_info := left_type_sym.info as table.Array
|
||||||
|
@ -254,13 +254,13 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type {
|
||||||
}
|
}
|
||||||
if method := c.table.type_find_method(left_type_sym, method_name) {
|
if method := c.table.type_find_method(left_type_sym, method_name) {
|
||||||
no_args := method.args.len - 1
|
no_args := method.args.len - 1
|
||||||
min_required_args := method.args.len - if method.is_variadic && method.args.len >
|
min_required_args := method.args.len - if method.is_variadic && method.args.len >
|
||||||
1 { 2 } else { 1 }
|
1 { 2 } else { 1 }
|
||||||
if call_expr.args.len < min_required_args {
|
if call_expr.args.len < min_required_args {
|
||||||
c.error('too few arguments in call to `${left_type_sym.name}.$method_name` ($call_expr.args.len instead of $min_required_args)',
|
c.error('too few arguments in call to `${left_type_sym.name}.$method_name` ($call_expr.args.len instead of $min_required_args)',
|
||||||
call_expr.pos)
|
call_expr.pos)
|
||||||
} else if !method.is_variadic && call_expr.args.len > no_args {
|
} else if !method.is_variadic && call_expr.args.len > no_args {
|
||||||
c.error('too many arguments in call to `${left_type_sym.name}.$method_name` ($call_expr.args.len instead of $no_args)',
|
c.error('too many arguments in call to `${left_type_sym.name}.$method_name` ($call_expr.args.len instead of $no_args)',
|
||||||
call_expr.pos)
|
call_expr.pos)
|
||||||
return method.return_type
|
return method.return_type
|
||||||
}
|
}
|
||||||
|
@ -352,10 +352,10 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type {
|
||||||
}
|
}
|
||||||
min_required_args := if f.is_variadic { f.args.len - 1 } else { f.args.len }
|
min_required_args := if f.is_variadic { f.args.len - 1 } else { f.args.len }
|
||||||
if call_expr.args.len < min_required_args {
|
if call_expr.args.len < min_required_args {
|
||||||
c.error('too few arguments in call to `$fn_name` ($call_expr.args.len instead of $min_required_args)',
|
c.error('too few arguments in call to `$fn_name` ($call_expr.args.len instead of $min_required_args)',
|
||||||
call_expr.pos)
|
call_expr.pos)
|
||||||
} else if !f.is_variadic && call_expr.args.len > f.args.len {
|
} else if !f.is_variadic && call_expr.args.len > f.args.len {
|
||||||
c.error('too many arguments in call to `$fn_name` ($call_expr.args.len instead of $f.args.len)',
|
c.error('too many arguments in call to `$fn_name` ($call_expr.args.len instead of $f.args.len)',
|
||||||
call_expr.pos)
|
call_expr.pos)
|
||||||
return f.return_type
|
return f.return_type
|
||||||
}
|
}
|
||||||
|
@ -389,7 +389,7 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type {
|
||||||
if typ_sym.kind == .array_fixed {
|
if typ_sym.kind == .array_fixed {
|
||||||
}
|
}
|
||||||
// println('fixed')
|
// println('fixed')
|
||||||
c.error('cannot use type `$typ_sym.str()` as type `$arg_typ_sym.str()` in argument ${i+1} to `$fn_name`',
|
c.error('cannot use type `$typ_sym.str()` as type `$arg_typ_sym.str()` in argument ${i+1} to `$fn_name`',
|
||||||
call_expr.pos)
|
call_expr.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -505,7 +505,7 @@ pub fn (c mut Checker) return_stmt(return_stmt mut ast.Return) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if return_stmt.exprs.len > 0 && c.fn_return_type == table.void_type {
|
if return_stmt.exprs.len > 0 && c.fn_return_type == table.void_type {
|
||||||
c.error('too many arguments to return, current function does not return anything',
|
c.error('too many arguments to return, current function does not return anything',
|
||||||
return_stmt.pos)
|
return_stmt.pos)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -536,7 +536,7 @@ pub fn (c mut Checker) return_stmt(return_stmt mut ast.Return) {
|
||||||
if !c.table.check(got_typ, exp_typ) {
|
if !c.table.check(got_typ, exp_typ) {
|
||||||
got_typ_sym := c.table.get_type_symbol(got_typ)
|
got_typ_sym := c.table.get_type_symbol(got_typ)
|
||||||
exp_typ_sym := c.table.get_type_symbol(exp_typ)
|
exp_typ_sym := c.table.get_type_symbol(exp_typ)
|
||||||
c.error('cannot use `$got_typ_sym.name` as type `$exp_typ_sym.name` in return argument',
|
c.error('cannot use `$got_typ_sym.name` as type `$exp_typ_sym.name` in return argument',
|
||||||
return_stmt.pos)
|
return_stmt.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -569,7 +569,7 @@ pub fn (c mut Checker) assign_stmt(assign_stmt mut ast.AssignStmt) {
|
||||||
if !c.table.check(val_type, var_type) {
|
if !c.table.check(val_type, var_type) {
|
||||||
val_type_sym := c.table.get_type_symbol(val_type)
|
val_type_sym := c.table.get_type_symbol(val_type)
|
||||||
var_type_sym := c.table.get_type_symbol(var_type)
|
var_type_sym := c.table.get_type_symbol(var_type)
|
||||||
c.error('assign stmt: cannot use `$val_type_sym.name` as `$var_type_sym.name`',
|
c.error('assign stmt: cannot use `$val_type_sym.name` as `$var_type_sym.name`',
|
||||||
assign_stmt.pos)
|
assign_stmt.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -597,7 +597,7 @@ pub fn (c mut Checker) assign_stmt(assign_stmt mut ast.AssignStmt) {
|
||||||
if !c.table.check(val_type, var_type) {
|
if !c.table.check(val_type, var_type) {
|
||||||
val_type_sym := c.table.get_type_symbol(val_type)
|
val_type_sym := c.table.get_type_symbol(val_type)
|
||||||
var_type_sym := c.table.get_type_symbol(var_type)
|
var_type_sym := c.table.get_type_symbol(var_type)
|
||||||
c.error('assign stmt: cannot use `$val_type_sym.name` as `$var_type_sym.name`',
|
c.error('assign stmt: cannot use `$val_type_sym.name` as `$var_type_sym.name`',
|
||||||
assign_stmt.pos)
|
assign_stmt.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -848,7 +848,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type {
|
||||||
type_sym := c.table.get_type_symbol(it.typ)
|
type_sym := c.table.get_type_symbol(it.typ)
|
||||||
if expr_type_sym.kind == .sum_type {
|
if expr_type_sym.kind == .sum_type {
|
||||||
info := expr_type_sym.info as table.SumType
|
info := expr_type_sym.info as table.SumType
|
||||||
if !it.typ in info.variants {
|
if !(it.typ in info.variants) {
|
||||||
c.error('cannot cast `$expr_type_sym.name` to `$type_sym.name`', it.pos)
|
c.error('cannot cast `$expr_type_sym.name` to `$type_sym.name`', it.pos)
|
||||||
// c.error('only $info.variants can be casted to `$typ`', it.pos)
|
// c.error('only $info.variants can be casted to `$typ`', it.pos)
|
||||||
}
|
}
|
||||||
|
@ -1139,7 +1139,7 @@ pub fn (c mut Checker) if_expr(node mut ast.IfExpr) table.Type {
|
||||||
for i, branch in node.branches {
|
for i, branch in node.branches {
|
||||||
match branch.cond {
|
match branch.cond {
|
||||||
ast.ParExpr {
|
ast.ParExpr {
|
||||||
c.error('unnecessary `()` in an if condition. use `if expr {` instead of `if (expr) {`.',
|
c.error('unnecessary `()` in an if condition. use `if expr {` instead of `if (expr) {`.',
|
||||||
node.pos)
|
node.pos)
|
||||||
}
|
}
|
||||||
else {}
|
else {}
|
||||||
|
@ -1214,9 +1214,9 @@ pub fn (c mut Checker) index_expr(node mut ast.IndexExpr) table.Type {
|
||||||
// println('index expr left=$typ_sym.name $node.pos.line_nr')
|
// println('index expr left=$typ_sym.name $node.pos.line_nr')
|
||||||
// if typ_sym.kind == .array && (!(table.type_idx(index_type) in table.number_type_idxs) &&
|
// if typ_sym.kind == .array && (!(table.type_idx(index_type) in table.number_type_idxs) &&
|
||||||
// index_type_sym.kind != .enum_) {
|
// index_type_sym.kind != .enum_) {
|
||||||
if typ_sym.kind in [.array, .array_fixed] && !(table.is_number(index_type) || index_type_sym.kind ==
|
if typ_sym.kind in [.array, .array_fixed] && !(table.is_number(index_type) || index_type_sym.kind ==
|
||||||
.enum_) {
|
.enum_) {
|
||||||
c.error('non-integer index `$index_type_sym.name` (array type `$typ_sym.name`)',
|
c.error('non-integer index `$index_type_sym.name` (array type `$typ_sym.name`)',
|
||||||
node.pos)
|
node.pos)
|
||||||
} else if typ_sym.kind == .map && table.type_idx(index_type) != table.string_type_idx {
|
} else if typ_sym.kind == .map && table.type_idx(index_type) != table.string_type_idx {
|
||||||
c.error('non-string map index (map type `$typ_sym.name`)', node.pos)
|
c.error('non-string map index (map type `$typ_sym.name`)', node.pos)
|
||||||
|
@ -1243,7 +1243,7 @@ pub fn (c mut Checker) index_expr(node mut ast.IndexExpr) table.Type {
|
||||||
pub fn (c mut Checker) enum_val(node mut ast.EnumVal) table.Type {
|
pub fn (c mut Checker) enum_val(node mut ast.EnumVal) table.Type {
|
||||||
typ_idx := if node.enum_name == '' {
|
typ_idx := if node.enum_name == '' {
|
||||||
table.type_idx(c.expected_type)
|
table.type_idx(c.expected_type)
|
||||||
} else { //
|
} else { //
|
||||||
c.table.find_type_idx(node.enum_name)
|
c.table.find_type_idx(node.enum_name)
|
||||||
}
|
}
|
||||||
// println('checker: enum_val: $node.enum_name typeidx=$typ_idx')
|
// println('checker: enum_val: $node.enum_name typeidx=$typ_idx')
|
||||||
|
@ -1288,13 +1288,13 @@ pub fn (c mut Checker) map_init(node mut ast.MapInit) table.Type {
|
||||||
if !c.table.check(key_type, key0_type) {
|
if !c.table.check(key_type, key0_type) {
|
||||||
key0_type_sym := c.table.get_type_symbol(key0_type)
|
key0_type_sym := c.table.get_type_symbol(key0_type)
|
||||||
key_type_sym := c.table.get_type_symbol(key_type)
|
key_type_sym := c.table.get_type_symbol(key_type)
|
||||||
c.error('map init: cannot use `$key_type_sym.name` as `$key0_type_sym` for map key',
|
c.error('map init: cannot use `$key_type_sym.name` as `$key0_type_sym` for map key',
|
||||||
node.pos)
|
node.pos)
|
||||||
}
|
}
|
||||||
if !c.table.check(val_type, val0_type) {
|
if !c.table.check(val_type, val0_type) {
|
||||||
val0_type_sym := c.table.get_type_symbol(val0_type)
|
val0_type_sym := c.table.get_type_symbol(val0_type)
|
||||||
val_type_sym := c.table.get_type_symbol(val_type)
|
val_type_sym := c.table.get_type_symbol(val_type)
|
||||||
c.error('map init: cannot use `$val_type_sym.name` as `$val0_type_sym` for map value',
|
c.error('map init: cannot use `$val_type_sym.name` as `$val0_type_sym` for map value',
|
||||||
node.pos)
|
node.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string
|
||||||
indent: -1
|
indent: -1
|
||||||
}
|
}
|
||||||
g.init()
|
g.init()
|
||||||
//
|
//
|
||||||
mut autofree_used := false
|
mut autofree_used := false
|
||||||
for file in files {
|
for file in files {
|
||||||
g.file = file
|
g.file = file
|
||||||
|
@ -115,7 +115,7 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string
|
||||||
if g.is_test {
|
if g.is_test {
|
||||||
g.write_tests_main()
|
g.write_tests_main()
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
g.finish()
|
g.finish()
|
||||||
return g.hashes() + g.includes.str() + g.typedefs.str() + g.typedefs2.str() + g.definitions.str() +
|
return g.hashes() + g.includes.str() + g.typedefs.str() + g.typedefs2.str() + g.definitions.str() +
|
||||||
g.gowrappers.str() + g.stringliterals.str() + g.out.str()
|
g.gowrappers.str() + g.stringliterals.str() + g.out.str()
|
||||||
|
@ -141,7 +141,7 @@ pub fn (g mut Gen) init() {
|
||||||
g.write_sorted_types()
|
g.write_sorted_types()
|
||||||
g.write_multi_return_types()
|
g.write_multi_return_types()
|
||||||
g.definitions.writeln('// end of definitions #endif')
|
g.definitions.writeln('// end of definitions #endif')
|
||||||
//
|
//
|
||||||
g.stringliterals.writeln('')
|
g.stringliterals.writeln('')
|
||||||
g.stringliterals.writeln('// >> string literal consts')
|
g.stringliterals.writeln('// >> string literal consts')
|
||||||
g.stringliterals.writeln('void vinit_string_literals(){')
|
g.stringliterals.writeln('void vinit_string_literals(){')
|
||||||
|
@ -205,7 +205,7 @@ pub fn (g mut Gen) typ(t table.Type) string {
|
||||||
return styp
|
return styp
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
pub fn (g mut Gen) write_typedef_types() {
|
pub fn (g mut Gen) write_typedef_types() {
|
||||||
for typ in g.table.types {
|
for typ in g.table.types {
|
||||||
match typ.kind {
|
match typ.kind {
|
||||||
|
@ -821,7 +821,7 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
//
|
//
|
||||||
g.fn_args(it.args, it.is_variadic)
|
g.fn_args(it.args, it.is_variadic)
|
||||||
if it.no_body {
|
if it.no_body {
|
||||||
// Just a function header.
|
// Just a function header.
|
||||||
|
@ -840,9 +840,9 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
|
||||||
g.writeln('free(_const_os__args.data); // empty, inited in _vinit()')
|
g.writeln('free(_const_os__args.data); // empty, inited in _vinit()')
|
||||||
}
|
}
|
||||||
if g.pref.os == .windows {
|
if g.pref.os == .windows {
|
||||||
g.writeln('_const_os__args = os__init_os_args_wide(___argc, ___argv);')
|
g.writeln('\t_const_os__args = os__init_os_args_wide(___argc, ___argv);')
|
||||||
} else {
|
} else {
|
||||||
g.writeln('_const_os__args = os__init_os_args(___argc, (byteptr*)___argv);')
|
g.writeln('\t_const_os__args = os__init_os_args(___argc, (byteptr*)___argv);')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1123,7 +1123,9 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||||
}
|
}
|
||||||
// g.write('/*pref*/')
|
// g.write('/*pref*/')
|
||||||
g.write(it.op.str())
|
g.write(it.op.str())
|
||||||
|
//g.write('(')
|
||||||
g.expr(it.right)
|
g.expr(it.right)
|
||||||
|
//g.write(')')
|
||||||
g.is_amp = false
|
g.is_amp = false
|
||||||
}
|
}
|
||||||
ast.SizeOf {
|
ast.SizeOf {
|
||||||
|
@ -1390,7 +1392,8 @@ fn (g mut Gen) infix_expr(node ast.InfixExpr) {
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.write('), $tmp, $elem_type_str)')
|
g.write('), $tmp, $elem_type_str)')
|
||||||
}
|
}
|
||||||
} 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 ] {
|
} 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] {
|
||||||
// floats should be compared with epsilon
|
// floats should be compared with epsilon
|
||||||
if node.left_type == table.f64_type_idx {
|
if node.left_type == table.f64_type_idx {
|
||||||
if node.op == .eq {
|
if node.op == .eq {
|
||||||
|
@ -1398,7 +1401,7 @@ fn (g mut Gen) infix_expr(node ast.InfixExpr) {
|
||||||
} else {
|
} else {
|
||||||
g.write('f64_ne(')
|
g.write('f64_ne(')
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
if node.op == .eq {
|
if node.op == .eq {
|
||||||
g.write('f32_eq(')
|
g.write('f32_eq(')
|
||||||
} else {
|
} else {
|
||||||
|
@ -1475,7 +1478,7 @@ fn (g mut Gen) match_expr(node ast.MatchExpr) {
|
||||||
// sum_type_str
|
// sum_type_str
|
||||||
} else if type_sym.kind == .string {
|
} else if type_sym.kind == .string {
|
||||||
g.write('string_eq(')
|
g.write('string_eq(')
|
||||||
//
|
//
|
||||||
g.expr(node.cond)
|
g.expr(node.cond)
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
// g.write('string_eq($tmp, ')
|
// g.write('string_eq($tmp, ')
|
||||||
|
@ -2159,7 +2162,7 @@ fn (g mut Gen) write_types(types []table.TypeSymbol) {
|
||||||
g.definitions.writeln('EMPTY_STRUCT_DECLARATION;')
|
g.definitions.writeln('EMPTY_STRUCT_DECLARATION;')
|
||||||
}
|
}
|
||||||
// g.definitions.writeln('} $name;\n')
|
// g.definitions.writeln('} $name;\n')
|
||||||
//
|
//
|
||||||
g.definitions.writeln('};\n')
|
g.definitions.writeln('};\n')
|
||||||
}
|
}
|
||||||
table.Alias {
|
table.Alias {
|
||||||
|
|
|
@ -863,7 +863,7 @@ fn (p mut Parser) prefix_expr() ast.PrefixExpr {
|
||||||
p.is_amp = true
|
p.is_amp = true
|
||||||
}
|
}
|
||||||
p.next()
|
p.next()
|
||||||
right := p.expr(1)
|
right := p.expr(token.Precedence.prefix)
|
||||||
p.is_amp = false
|
p.is_amp = false
|
||||||
return ast.PrefixExpr{
|
return ast.PrefixExpr{
|
||||||
op: op
|
op: op
|
||||||
|
|
|
@ -303,7 +303,7 @@ pub enum Precedence {
|
||||||
product // * or /
|
product // * or /
|
||||||
// mod // %
|
// mod // %
|
||||||
prefix // -X or !X
|
prefix // -X or !X
|
||||||
postfix
|
postfix // ++ or --
|
||||||
call // func(X) or foo.method(X)
|
call // func(X) or foo.method(X)
|
||||||
index // array[index], map[key]
|
index // array[index], map[key]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue