parser: handle casts in match expressions; c2v: minor fixes
parent
9fab4af3f1
commit
ca8158ac41
|
@ -1,7 +1,10 @@
|
||||||
-## V 0.2.4
|
-## V 0.2.4
|
||||||
-*Not yet released*
|
-*Not yet released, changelog is not full*
|
||||||
|
- String interpolation and struct stringers are now implemented in pure V
|
||||||
|
with a much cleaner and faster implementation. Previously libc's `sprintf`
|
||||||
|
was used.
|
||||||
- Improved `unused variable` warning. Assigning to a variable no longer marks it as used.
|
- Improved `unused variable` warning. Assigning to a variable no longer marks it as used.
|
||||||
- Bare metal support.
|
- Bare metal support. Vinix OS kernel is now being developed in V.
|
||||||
|
|
||||||
## V 0.2.2 - 0.2.3
|
## V 0.2.2 - 0.2.3
|
||||||
*22 Jan 2021*
|
*22 Jan 2021*
|
||||||
|
|
|
@ -43,7 +43,7 @@ pub fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type,
|
||||||
exp_sym := c.table.get_type_symbol(expected)
|
exp_sym := c.table.get_type_symbol(expected)
|
||||||
// unknown C types are set to int, allow int to be used for types like `&C.FILE`
|
// unknown C types are set to int, allow int to be used for types like `&C.FILE`
|
||||||
// eg. `C.fflush(C.stderr)` - error: cannot use `int` as `&C.FILE` in argument 1 to `C.fflush`
|
// eg. `C.fflush(C.stderr)` - error: cannot use `int` as `&C.FILE` in argument 1 to `C.fflush`
|
||||||
if expected.is_ptr() && exp_sym.language == .c && exp_sym.kind == .placeholder
|
if expected.is_ptr() && exp_sym.language == .c && exp_sym.kind in [.placeholder, .struct_]
|
||||||
&& got == ast.int_type_idx {
|
&& got == ast.int_type_idx {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -880,7 +880,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) ast.Type {
|
||||||
}
|
}
|
||||||
if obj.is_stack_obj && !c.inside_unsafe {
|
if obj.is_stack_obj && !c.inside_unsafe {
|
||||||
sym := c.table.get_type_symbol(obj.typ.set_nr_muls(0))
|
sym := c.table.get_type_symbol(obj.typ.set_nr_muls(0))
|
||||||
if !sym.is_heap() {
|
if !sym.is_heap() && !c.pref.translated {
|
||||||
suggestion := if sym.kind == .struct_ {
|
suggestion := if sym.kind == .struct_ {
|
||||||
'declaring `$sym.name` as `[heap]`'
|
'declaring `$sym.name` as `[heap]`'
|
||||||
} else {
|
} else {
|
||||||
|
@ -1300,12 +1300,14 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) ast.Type {
|
||||||
return ast.void_type
|
return ast.void_type
|
||||||
}
|
}
|
||||||
.and, .logical_or {
|
.and, .logical_or {
|
||||||
|
if !c.pref.translated {
|
||||||
if infix_expr.left_type != ast.bool_type_idx {
|
if infix_expr.left_type != ast.bool_type_idx {
|
||||||
c.error('left operand for `$infix_expr.op` is not a boolean', infix_expr.left.position())
|
c.error('left operand for `$infix_expr.op` is not a boolean', infix_expr.left.position())
|
||||||
}
|
}
|
||||||
if infix_expr.right_type != ast.bool_type_idx {
|
if infix_expr.right_type != ast.bool_type_idx {
|
||||||
c.error('right operand for `$infix_expr.op` is not a boolean', infix_expr.right.position())
|
c.error('right operand for `$infix_expr.op` is not a boolean', infix_expr.right.position())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if mut infix_expr.left is ast.InfixExpr {
|
if mut infix_expr.left is ast.InfixExpr {
|
||||||
if infix_expr.left.op != infix_expr.op && infix_expr.left.op in [.logical_or, .and] {
|
if infix_expr.left.op != infix_expr.op && infix_expr.left.op in [.logical_or, .and] {
|
||||||
// for example: `(a && b) || c` instead of `a && b || c`
|
// for example: `(a && b) || c` instead of `a && b || c`
|
||||||
|
@ -1334,7 +1336,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) ast.Type {
|
||||||
c.error('only `==`, `!=`, `|` and `&` are defined on `[flag]` tagged `enum`, use an explicit cast to `int` if needed',
|
c.error('only `==`, `!=`, `|` and `&` are defined on `[flag]` tagged `enum`, use an explicit cast to `int` if needed',
|
||||||
infix_expr.pos)
|
infix_expr.pos)
|
||||||
}
|
}
|
||||||
} else {
|
} else if !c.pref.translated {
|
||||||
// Regular enums
|
// Regular enums
|
||||||
c.error('only `==` and `!=` are defined on `enum`, use an explicit cast to `int` if needed',
|
c.error('only `==` and `!=` are defined on `enum`, use an explicit cast to `int` if needed',
|
||||||
infix_expr.pos)
|
infix_expr.pos)
|
||||||
|
@ -3075,7 +3077,7 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
|
||||||
}
|
}
|
||||||
if obj.is_stack_obj && !c.inside_unsafe {
|
if obj.is_stack_obj && !c.inside_unsafe {
|
||||||
type_sym := c.table.get_type_symbol(obj.typ.set_nr_muls(0))
|
type_sym := c.table.get_type_symbol(obj.typ.set_nr_muls(0))
|
||||||
if !type_sym.is_heap() {
|
if !type_sym.is_heap() && !c.pref.translated {
|
||||||
suggestion := if type_sym.kind == .struct_ {
|
suggestion := if type_sym.kind == .struct_ {
|
||||||
'declaring `$type_sym.name` as `[heap]`'
|
'declaring `$type_sym.name` as `[heap]`'
|
||||||
} else {
|
} else {
|
||||||
|
@ -3331,7 +3333,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
||||||
}
|
}
|
||||||
if obj.is_stack_obj && !c.inside_unsafe {
|
if obj.is_stack_obj && !c.inside_unsafe {
|
||||||
type_sym := c.table.get_type_symbol(obj.typ.set_nr_muls(0))
|
type_sym := c.table.get_type_symbol(obj.typ.set_nr_muls(0))
|
||||||
if !type_sym.is_heap() {
|
if !type_sym.is_heap() && !c.pref.translated {
|
||||||
suggestion := if type_sym.kind == .struct_ {
|
suggestion := if type_sym.kind == .struct_ {
|
||||||
'declaring `$type_sym.name` as `[heap]`'
|
'declaring `$type_sym.name` as `[heap]`'
|
||||||
} else {
|
} else {
|
||||||
|
@ -6274,14 +6276,16 @@ pub fn (mut c Checker) mark_as_referenced(mut node ast.Expr) {
|
||||||
obj = c.fn_scope.find_var(node.obj.name) or { obj }
|
obj = c.fn_scope.find_var(node.obj.name) or { obj }
|
||||||
}
|
}
|
||||||
type_sym := c.table.get_type_symbol(obj.typ.set_nr_muls(0))
|
type_sym := c.table.get_type_symbol(obj.typ.set_nr_muls(0))
|
||||||
if obj.is_stack_obj && !type_sym.is_heap() {
|
if obj.is_stack_obj && !type_sym.is_heap() && !c.pref.translated {
|
||||||
suggestion := if type_sym.kind == .struct_ {
|
suggestion := if type_sym.kind == .struct_ {
|
||||||
'declaring `$type_sym.name` as `[heap]`'
|
'declaring `$type_sym.name` as `[heap]`'
|
||||||
} else {
|
} else {
|
||||||
'wrapping the `$type_sym.name` object in a `struct` declared as `[heap]`'
|
'wrapping the `$type_sym.name` object in a `struct` declared as `[heap]`'
|
||||||
}
|
}
|
||||||
|
if !c.pref.translated {
|
||||||
c.error('`$node.name` cannot be referenced outside `unsafe` blocks as it might be stored on stack. Consider ${suggestion}.',
|
c.error('`$node.name` cannot be referenced outside `unsafe` blocks as it might be stored on stack. Consider ${suggestion}.',
|
||||||
node.pos)
|
node.pos)
|
||||||
|
}
|
||||||
} else if type_sym.kind == .array_fixed {
|
} else if type_sym.kind == .array_fixed {
|
||||||
c.error('cannot reference fixed array `$node.name` outside `unsafe` blocks as it is supposed to be stored on stack',
|
c.error('cannot reference fixed array `$node.name` outside `unsafe` blocks as it is supposed to be stored on stack',
|
||||||
node.pos)
|
node.pos)
|
||||||
|
|
|
@ -3137,6 +3137,7 @@ fn (mut g Gen) expr(node ast.Expr) {
|
||||||
}
|
}
|
||||||
ast.EnumVal {
|
ast.EnumVal {
|
||||||
// g.write('${it.mod}${it.enum_name}_$it.val')
|
// g.write('${it.mod}${it.enum_name}_$it.val')
|
||||||
|
// g.enum_expr(node)
|
||||||
styp := g.typ(node.typ)
|
styp := g.typ(node.typ)
|
||||||
g.write('${styp}_$node.val')
|
g.write('${styp}_$node.val')
|
||||||
}
|
}
|
||||||
|
@ -3482,8 +3483,12 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
|
||||||
|
|
||||||
fn (mut g Gen) enum_expr(node ast.Expr) {
|
fn (mut g Gen) enum_expr(node ast.Expr) {
|
||||||
match node {
|
match node {
|
||||||
ast.EnumVal { g.write(node.val) }
|
ast.EnumVal {
|
||||||
else { g.expr(node) }
|
g.write(node.val)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g.expr(node)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,8 +178,8 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
|
||||||
is_else = true
|
is_else = true
|
||||||
p.next()
|
p.next()
|
||||||
} else if (p.tok.kind == .name && !(p.tok.lit == 'C' && p.peek_tok.kind == .dot)
|
} else if (p.tok.kind == .name && !(p.tok.lit == 'C' && p.peek_tok.kind == .dot)
|
||||||
&& (p.tok.lit in ast.builtin_type_names || p.tok.lit[0].is_capital()
|
&& (((p.tok.lit in ast.builtin_type_names || p.tok.lit[0].is_capital())
|
||||||
|| (p.peek_tok.kind == .dot && p.peek_token(2).lit.len > 0
|
&& p.peek_tok.kind != .lpar) || (p.peek_tok.kind == .dot && p.peek_token(2).lit.len > 0
|
||||||
&& p.peek_token(2).lit[0].is_capital()))) || p.tok.kind == .lsbr {
|
&& p.peek_token(2).lit[0].is_capital()))) || p.tok.kind == .lsbr {
|
||||||
mut types := []ast.Type{}
|
mut types := []ast.Type{}
|
||||||
for {
|
for {
|
||||||
|
|
|
@ -19,7 +19,7 @@ fn test_match_integers() {
|
||||||
println('three')
|
println('three')
|
||||||
b = 3
|
b = 3
|
||||||
}
|
}
|
||||||
4 {
|
int(4) {
|
||||||
println('four')
|
println('four')
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
Loading…
Reference in New Issue