cgen: print results of failed callexprs in `assert fn() == fn2()` (#6665)
parent
6d11caf784
commit
ab137e4164
|
@ -9,8 +9,8 @@ import v.errors
|
||||||
|
|
||||||
pub type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl
|
pub type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl
|
||||||
|
|
||||||
pub type Expr = AnonFn | ArrayInit | AsCast | Assoc | BoolLiteral | CallExpr | CastExpr |
|
pub type Expr = AnonFn | ArrayInit | AsCast | Assoc | BoolLiteral | CTempVar | CallExpr |
|
||||||
ChanInit | CharLiteral | Comment | ComptimeCall | ConcatExpr | EnumVal | FloatLiteral |
|
CastExpr | ChanInit | CharLiteral | Comment | ComptimeCall | ConcatExpr | EnumVal | FloatLiteral |
|
||||||
Ident | IfExpr | IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | Likely | LockExpr |
|
Ident | IfExpr | IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | Likely | LockExpr |
|
||||||
MapInit | MatchExpr | None | OrExpr | ParExpr | PostfixExpr | PrefixExpr | RangeExpr |
|
MapInit | MatchExpr | None | OrExpr | ParExpr | PostfixExpr | PrefixExpr | RangeExpr |
|
||||||
SelectExpr | SelectorExpr | SizeOf | SqlExpr | StringInterLiteral | StringLiteral | StructInit |
|
SelectExpr | SelectorExpr | SizeOf | SqlExpr | StringInterLiteral | StringLiteral | StructInit |
|
||||||
|
@ -439,9 +439,9 @@ pub struct InfixExpr {
|
||||||
pub:
|
pub:
|
||||||
op token.Kind
|
op token.Kind
|
||||||
pos token.Position
|
pos token.Position
|
||||||
|
pub mut:
|
||||||
left Expr
|
left Expr
|
||||||
right Expr
|
right Expr
|
||||||
pub mut:
|
|
||||||
left_type table.Type
|
left_type table.Type
|
||||||
right_type table.Type
|
right_type table.Type
|
||||||
auto_locked string
|
auto_locked string
|
||||||
|
@ -826,8 +826,9 @@ pub mut:
|
||||||
|
|
||||||
pub struct AssertStmt {
|
pub struct AssertStmt {
|
||||||
pub:
|
pub:
|
||||||
expr Expr
|
|
||||||
pos token.Position
|
pos token.Position
|
||||||
|
pub mut:
|
||||||
|
expr Expr
|
||||||
}
|
}
|
||||||
|
|
||||||
// `if [x := opt()] {`
|
// `if [x := opt()] {`
|
||||||
|
@ -1025,6 +1026,7 @@ pub fn (expr Expr) position() token.Position {
|
||||||
pub fn (expr Expr) is_lvalue() bool {
|
pub fn (expr Expr) is_lvalue() bool {
|
||||||
match expr {
|
match expr {
|
||||||
Ident { return true }
|
Ident { return true }
|
||||||
|
CTempVar { return true }
|
||||||
IndexExpr { return expr.left.is_lvalue() }
|
IndexExpr { return expr.left.is_lvalue() }
|
||||||
SelectorExpr { return expr.expr.is_lvalue() }
|
SelectorExpr { return expr.expr.is_lvalue() }
|
||||||
else {}
|
else {}
|
||||||
|
@ -1058,6 +1060,15 @@ pub fn (stmt Stmt) check_c_expr() ? {
|
||||||
return error('unsupported statement (`${typeof(stmt)}`)')
|
return error('unsupported statement (`${typeof(stmt)}`)')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CTempVar is used in cgen only, to hold nodes for temporary variables
|
||||||
|
pub struct CTempVar {
|
||||||
|
pub:
|
||||||
|
name string // the name of the C temporary variable; used by g.expr(x)
|
||||||
|
orig Expr // the original expression, which produced the C temp variable; used by x.str()
|
||||||
|
typ table.Type // the type of the original expression
|
||||||
|
is_ptr bool // whether the type is a pointer
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (stmt Stmt) position() token.Position {
|
pub fn (stmt Stmt) position() token.Position {
|
||||||
match stmt {
|
match stmt {
|
||||||
AssertStmt, AssignStmt, Block, ConstDecl, EnumDecl, ExprStmt, FnDecl, ForCStmt, ForInStmt, ForStmt, Import, Return, StructDecl { return stmt.pos }
|
AssertStmt, AssignStmt, Block, ConstDecl, EnumDecl, ExprStmt, FnDecl, ForCStmt, ForInStmt, ForStmt, Import, Return, StructDecl { return stmt.pos }
|
||||||
|
|
|
@ -177,6 +177,9 @@ pub fn (lit &StringInterLiteral) get_fspec_braces(i int) (string, bool) {
|
||||||
// string representation of expr
|
// string representation of expr
|
||||||
pub fn (x Expr) str() string {
|
pub fn (x Expr) str() string {
|
||||||
match x {
|
match x {
|
||||||
|
CTempVar {
|
||||||
|
return x.orig.str()
|
||||||
|
}
|
||||||
BoolLiteral {
|
BoolLiteral {
|
||||||
return x.val.str()
|
return x.val.str()
|
||||||
}
|
}
|
||||||
|
@ -188,6 +191,9 @@ pub fn (x Expr) str() string {
|
||||||
if x.is_method {
|
if x.is_method {
|
||||||
return '${x.left.str()}.${x.name}($sargs)'
|
return '${x.left.str()}.${x.name}($sargs)'
|
||||||
}
|
}
|
||||||
|
if x.name.starts_with('${x.mod}.') {
|
||||||
|
return util.strip_main_name('${x.name}($sargs)')
|
||||||
|
}
|
||||||
return '${x.mod}.${x.name}($sargs)'
|
return '${x.mod}.${x.name}($sargs)'
|
||||||
}
|
}
|
||||||
CharLiteral {
|
CharLiteral {
|
||||||
|
|
|
@ -2563,6 +2563,9 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
|
||||||
return table.void_type
|
return table.void_type
|
||||||
}
|
}
|
||||||
match mut node {
|
match mut node {
|
||||||
|
ast.CTempVar {
|
||||||
|
return node.typ
|
||||||
|
}
|
||||||
ast.AnonFn {
|
ast.AnonFn {
|
||||||
keep_fn := c.cur_fn
|
keep_fn := c.cur_fn
|
||||||
c.cur_fn = &node.decl
|
c.cur_fn = &node.decl
|
||||||
|
|
|
@ -711,6 +711,9 @@ pub fn (mut f Fmt) expr(node ast.Expr) {
|
||||||
eprintln('expr: ${node.position():-42} | node: ${typeof(node):-20} | $node.str()')
|
eprintln('expr: ${node.position():-42} | node: ${typeof(node):-20} | $node.str()')
|
||||||
}
|
}
|
||||||
match mut node {
|
match mut node {
|
||||||
|
ast.CTempVar {
|
||||||
|
eprintln('ast.CTempVar of $node.orig.str() should be generated/used only in cgen')
|
||||||
|
}
|
||||||
ast.AnonFn {
|
ast.AnonFn {
|
||||||
f.fn_decl(node.decl)
|
f.fn_decl(node.decl)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1272,8 +1272,40 @@ fn (mut g Gen) gen_attrs(attrs []table.Attr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) gen_assert_stmt(a ast.AssertStmt) {
|
fn (mut g Gen) gen_assert_stmt(original_assert_statement ast.AssertStmt) {
|
||||||
|
mut a := original_assert_statement
|
||||||
g.writeln('// assert')
|
g.writeln('// assert')
|
||||||
|
mut tl_name := ''
|
||||||
|
mut tr_name := ''
|
||||||
|
if a.expr is ast.InfixExpr {
|
||||||
|
mut aie := a.expr as ast.InfixExpr
|
||||||
|
if aie.left is ast.CallExpr {
|
||||||
|
tl_styp := g.typ(aie.left_type)
|
||||||
|
tl_name = g.new_tmp_var()
|
||||||
|
g.write('$tl_styp $tl_name = ')
|
||||||
|
g.expr(aie.left)
|
||||||
|
g.writeln(';')
|
||||||
|
aie.left = ast.Expr(ast.CTempVar{
|
||||||
|
name: tl_name
|
||||||
|
typ: aie.left_type
|
||||||
|
is_ptr: aie.left_type.is_ptr()
|
||||||
|
orig: aie.left
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if aie.right is ast.CallExpr {
|
||||||
|
tr_styp := g.typ(aie.right_type)
|
||||||
|
tr_name = g.new_tmp_var()
|
||||||
|
g.write('$tr_styp $tr_name = ')
|
||||||
|
g.expr(aie.right)
|
||||||
|
g.writeln(';')
|
||||||
|
aie.right = ast.Expr(ast.CTempVar{
|
||||||
|
name: tr_name
|
||||||
|
typ: aie.right_type
|
||||||
|
is_ptr: aie.right_type.is_ptr()
|
||||||
|
orig: aie.right
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
g.inside_ternary++
|
g.inside_ternary++
|
||||||
g.write('if (')
|
g.write('if (')
|
||||||
g.expr(a.expr)
|
g.expr(a.expr)
|
||||||
|
@ -1338,7 +1370,7 @@ fn (mut g Gen) gen_assert_metainfo(a ast.AssertStmt) string {
|
||||||
fn (mut g Gen) gen_assert_single_expr(e ast.Expr, t table.Type) {
|
fn (mut g Gen) gen_assert_single_expr(e ast.Expr, t table.Type) {
|
||||||
unknown_value := '*unknown value*'
|
unknown_value := '*unknown value*'
|
||||||
match e {
|
match e {
|
||||||
ast.CallExpr, ast.CastExpr, ast.IndexExpr, ast.PrefixExpr, ast.MatchExpr {
|
ast.CastExpr, ast.IndexExpr, ast.PrefixExpr, ast.MatchExpr {
|
||||||
g.write(ctoslit(unknown_value))
|
g.write(ctoslit(unknown_value))
|
||||||
}
|
}
|
||||||
ast.Type {
|
ast.Type {
|
||||||
|
@ -1962,6 +1994,7 @@ fn (mut g Gen) gen_anon_fn_decl(it ast.AnonFn) {
|
||||||
|
|
||||||
fn (mut g Gen) expr(node ast.Expr) {
|
fn (mut g Gen) expr(node ast.Expr) {
|
||||||
// println('cgen expr() line_nr=$node.pos.line_nr')
|
// println('cgen expr() line_nr=$node.pos.line_nr')
|
||||||
|
// NB: please keep the type names in the match here in alphabetical order:
|
||||||
match node {
|
match node {
|
||||||
ast.AnonFn {
|
ast.AnonFn {
|
||||||
// TODO: dont fiddle with buffers
|
// TODO: dont fiddle with buffers
|
||||||
|
@ -2084,6 +2117,10 @@ fn (mut g Gen) expr(node ast.Expr) {
|
||||||
ast.ConcatExpr {
|
ast.ConcatExpr {
|
||||||
g.concat_expr(node)
|
g.concat_expr(node)
|
||||||
}
|
}
|
||||||
|
ast.CTempVar {
|
||||||
|
// g.write('/*ctmp .orig: $node.orig.str() , .typ: $node.typ, .is_ptr: $node.is_ptr */ ')
|
||||||
|
g.write(node.name)
|
||||||
|
}
|
||||||
ast.EnumVal {
|
ast.EnumVal {
|
||||||
// g.write('${it.mod}${it.enum_name}_$it.val')
|
// g.write('${it.mod}${it.enum_name}_$it.val')
|
||||||
styp := g.typ(node.typ)
|
styp := g.typ(node.typ)
|
||||||
|
@ -4366,6 +4403,11 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype table.Type) ?bool {
|
||||||
g.write('($s)')
|
g.write('($s)')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if expr is ast.CTempVar {
|
||||||
|
if expr.is_ptr {
|
||||||
|
g.write('*')
|
||||||
|
}
|
||||||
|
}
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
if sym.kind == .struct_ && !sym_has_str_method {
|
if sym.kind == .struct_ && !sym_has_str_method {
|
||||||
if is_p {
|
if is_p {
|
||||||
|
|
|
@ -520,6 +520,9 @@ fn (mut g JsGen) stmt(node ast.Stmt) {
|
||||||
|
|
||||||
fn (mut g JsGen) expr(node ast.Expr) {
|
fn (mut g JsGen) expr(node ast.Expr) {
|
||||||
match node {
|
match node {
|
||||||
|
ast.CTempVar {
|
||||||
|
g.write('/* ast.CTempVar: node.name */')
|
||||||
|
}
|
||||||
ast.AnonFn {
|
ast.AnonFn {
|
||||||
g.gen_fn_decl(node.decl)
|
g.gen_fn_decl(node.decl)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue