Merge branch 'main' into bugfix

This commit is contained in:
Richard Feldman 2025-11-30 18:27:11 -05:00 committed by GitHub
commit fede35c9c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 894 additions and 2 deletions

View file

@ -10948,7 +10948,10 @@ pub const Interpreter = struct {
if (lambda_expr == .e_low_level_lambda) {
const low_level = lambda_expr.e_low_level_lambda;
var args = [1]StackValue{receiver_value};
const result = try self.callLowLevelBuiltin(low_level.op, &args, roc_ops, null);
// Get return type from the dot access expression for low-level builtins that need it
const return_ct_var = can.ModuleEnv.varFrom(da.expr_idx);
const return_rt_var = try self.translateTypeVar(self.env, return_ct_var);
const result = try self.callLowLevelBuiltin(low_level.op, &args, roc_ops, return_rt_var);
receiver_value.decref(&self.runtime_layout_store, roc_ops);
method_func.decref(&self.runtime_layout_store, roc_ops);
self.env = saved_env;
@ -11069,7 +11072,10 @@ pub const Interpreter = struct {
all_args[1 + idx] = arg;
}
const result = try self.callLowLevelBuiltin(low_level.op, all_args, roc_ops, null);
// Get return type from the dot access expression for low-level builtins that need it
const return_ct_var = can.ModuleEnv.varFrom(dac.expr_idx);
const return_rt_var = try self.translateTypeVar(self.env, return_ct_var);
const result = try self.callLowLevelBuiltin(low_level.op, all_args, roc_ops, return_rt_var);
receiver_value.decref(&self.runtime_layout_store, roc_ops);
for (arg_values) |arg| arg.decref(&self.runtime_layout_store, roc_ops);

View file

@ -0,0 +1,136 @@
# META
~~~ini
description=Record with I64 field type and arithmetic operation
type=snippet
~~~
# SOURCE
~~~roc
Robot : { x : I64, y : I64 }
advance : Robot -> Robot
advance = |robot| { ..robot, y: robot.y + 1 }
expect advance({ x: 7, y: 3 }) == { x: 7, y: 4 }
~~~
# EXPECTED
NIL
# PROBLEMS
NIL
# TOKENS
~~~zig
UpperIdent,OpColon,OpenCurly,LowerIdent,OpColon,UpperIdent,Comma,LowerIdent,OpColon,UpperIdent,CloseCurly,
LowerIdent,OpColon,UpperIdent,OpArrow,UpperIdent,
LowerIdent,OpAssign,OpBar,LowerIdent,OpBar,OpenCurly,DoubleDot,LowerIdent,Comma,LowerIdent,OpColon,LowerIdent,NoSpaceDotLowerIdent,OpPlus,Int,CloseCurly,
KwExpect,LowerIdent,NoSpaceOpenRound,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,CloseRound,OpEquals,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,
EndOfFile,
~~~
# PARSE
~~~clojure
(file
(type-module)
(statements
(s-type-decl
(header (name "Robot")
(args))
(ty-record
(anno-record-field (name "x")
(ty (name "I64")))
(anno-record-field (name "y")
(ty (name "I64")))))
(s-type-anno (name "advance")
(ty-fn
(ty (name "Robot"))
(ty (name "Robot"))))
(s-decl
(p-ident (raw "advance"))
(e-lambda
(args
(p-ident (raw "robot")))
(e-record
(ext
(e-ident (raw "robot")))
(field (field "y")
(e-binop (op "+")
(e-field-access
(e-ident (raw "robot"))
(e-ident (raw "y")))
(e-int (raw "1")))))))
(s-expect
(e-binop (op "==")
(e-apply
(e-ident (raw "advance"))
(e-record
(field (field "x")
(e-int (raw "7")))
(field (field "y")
(e-int (raw "3")))))
(e-record
(field (field "x")
(e-int (raw "7")))
(field (field "y")
(e-int (raw "4"))))))))
~~~
# FORMATTED
~~~roc
NO CHANGE
~~~
# CANONICALIZE
~~~clojure
(can-ir
(d-let
(p-assign (ident "advance"))
(e-lambda
(args
(p-assign (ident "robot")))
(e-record
(ext
(e-lookup-local
(p-assign (ident "robot"))))
(fields
(field (name "y")
(e-binop (op "add")
(e-dot-access (field "y")
(receiver
(e-lookup-local
(p-assign (ident "robot")))))
(e-num (value "1")))))))
(annotation
(ty-fn (effectful false)
(ty-lookup (name "Robot") (local))
(ty-lookup (name "Robot") (local)))))
(s-alias-decl
(ty-header (name "Robot"))
(ty-record
(field (field "x")
(ty-lookup (name "I64") (builtin)))
(field (field "y")
(ty-lookup (name "I64") (builtin)))))
(s-expect
(e-binop (op "eq")
(e-call
(e-lookup-local
(p-assign (ident "advance")))
(e-record
(fields
(field (name "x")
(e-num (value "7")))
(field (name "y")
(e-num (value "3"))))))
(e-record
(fields
(field (name "x")
(e-num (value "7")))
(field (name "y")
(e-num (value "4"))))))))
~~~
# TYPES
~~~clojure
(inferred-types
(defs
(patt (type "Robot -> Robot")))
(type_decls
(alias (type "Robot")
(ty-header (name "Robot"))))
(expressions
(expr (type "Robot -> Robot"))))
~~~

View file

@ -0,0 +1,253 @@
# META
~~~ini
description=Record update with I64 field type and arithmetic
type=snippet
~~~
# SOURCE
~~~roc
Robot : { x : I64, y : I64 }
advance : Robot -> Robot
advance = |robot| { ..robot, y: robot.y + 1 }
retreat : Robot -> Robot
retreat = |robot| { ..robot, y: robot.y - 1 }
expect advance({ x: 7, y: 3 }) == { x: 7, y: 4 }
expect retreat({ x: 7, y: 3 }) == { x: 7, y: 2 }
expect advance(retreat({ x: 0, y: 0 })) == { x: 0, y: 0 }
~~~
# EXPECTED
NIL
# PROBLEMS
NIL
# TOKENS
~~~zig
UpperIdent,OpColon,OpenCurly,LowerIdent,OpColon,UpperIdent,Comma,LowerIdent,OpColon,UpperIdent,CloseCurly,
LowerIdent,OpColon,UpperIdent,OpArrow,UpperIdent,
LowerIdent,OpAssign,OpBar,LowerIdent,OpBar,OpenCurly,DoubleDot,LowerIdent,Comma,LowerIdent,OpColon,LowerIdent,NoSpaceDotLowerIdent,OpPlus,Int,CloseCurly,
LowerIdent,OpColon,UpperIdent,OpArrow,UpperIdent,
LowerIdent,OpAssign,OpBar,LowerIdent,OpBar,OpenCurly,DoubleDot,LowerIdent,Comma,LowerIdent,OpColon,LowerIdent,NoSpaceDotLowerIdent,OpBinaryMinus,Int,CloseCurly,
KwExpect,LowerIdent,NoSpaceOpenRound,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,CloseRound,OpEquals,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,
KwExpect,LowerIdent,NoSpaceOpenRound,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,CloseRound,OpEquals,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,
KwExpect,LowerIdent,NoSpaceOpenRound,LowerIdent,NoSpaceOpenRound,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,CloseRound,CloseRound,OpEquals,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,
EndOfFile,
~~~
# PARSE
~~~clojure
(file
(type-module)
(statements
(s-type-decl
(header (name "Robot")
(args))
(ty-record
(anno-record-field (name "x")
(ty (name "I64")))
(anno-record-field (name "y")
(ty (name "I64")))))
(s-type-anno (name "advance")
(ty-fn
(ty (name "Robot"))
(ty (name "Robot"))))
(s-decl
(p-ident (raw "advance"))
(e-lambda
(args
(p-ident (raw "robot")))
(e-record
(ext
(e-ident (raw "robot")))
(field (field "y")
(e-binop (op "+")
(e-field-access
(e-ident (raw "robot"))
(e-ident (raw "y")))
(e-int (raw "1")))))))
(s-type-anno (name "retreat")
(ty-fn
(ty (name "Robot"))
(ty (name "Robot"))))
(s-decl
(p-ident (raw "retreat"))
(e-lambda
(args
(p-ident (raw "robot")))
(e-record
(ext
(e-ident (raw "robot")))
(field (field "y")
(e-binop (op "-")
(e-field-access
(e-ident (raw "robot"))
(e-ident (raw "y")))
(e-int (raw "1")))))))
(s-expect
(e-binop (op "==")
(e-apply
(e-ident (raw "advance"))
(e-record
(field (field "x")
(e-int (raw "7")))
(field (field "y")
(e-int (raw "3")))))
(e-record
(field (field "x")
(e-int (raw "7")))
(field (field "y")
(e-int (raw "4"))))))
(s-expect
(e-binop (op "==")
(e-apply
(e-ident (raw "retreat"))
(e-record
(field (field "x")
(e-int (raw "7")))
(field (field "y")
(e-int (raw "3")))))
(e-record
(field (field "x")
(e-int (raw "7")))
(field (field "y")
(e-int (raw "2"))))))
(s-expect
(e-binop (op "==")
(e-apply
(e-ident (raw "advance"))
(e-apply
(e-ident (raw "retreat"))
(e-record
(field (field "x")
(e-int (raw "0")))
(field (field "y")
(e-int (raw "0"))))))
(e-record
(field (field "x")
(e-int (raw "0")))
(field (field "y")
(e-int (raw "0"))))))))
~~~
# FORMATTED
~~~roc
NO CHANGE
~~~
# CANONICALIZE
~~~clojure
(can-ir
(d-let
(p-assign (ident "advance"))
(e-lambda
(args
(p-assign (ident "robot")))
(e-record
(ext
(e-lookup-local
(p-assign (ident "robot"))))
(fields
(field (name "y")
(e-binop (op "add")
(e-dot-access (field "y")
(receiver
(e-lookup-local
(p-assign (ident "robot")))))
(e-num (value "1")))))))
(annotation
(ty-fn (effectful false)
(ty-lookup (name "Robot") (local))
(ty-lookup (name "Robot") (local)))))
(d-let
(p-assign (ident "retreat"))
(e-lambda
(args
(p-assign (ident "robot")))
(e-record
(ext
(e-lookup-local
(p-assign (ident "robot"))))
(fields
(field (name "y")
(e-binop (op "sub")
(e-dot-access (field "y")
(receiver
(e-lookup-local
(p-assign (ident "robot")))))
(e-num (value "1")))))))
(annotation
(ty-fn (effectful false)
(ty-lookup (name "Robot") (local))
(ty-lookup (name "Robot") (local)))))
(s-alias-decl
(ty-header (name "Robot"))
(ty-record
(field (field "x")
(ty-lookup (name "I64") (builtin)))
(field (field "y")
(ty-lookup (name "I64") (builtin)))))
(s-expect
(e-binop (op "eq")
(e-call
(e-lookup-local
(p-assign (ident "advance")))
(e-record
(fields
(field (name "x")
(e-num (value "7")))
(field (name "y")
(e-num (value "3"))))))
(e-record
(fields
(field (name "x")
(e-num (value "7")))
(field (name "y")
(e-num (value "4")))))))
(s-expect
(e-binop (op "eq")
(e-call
(e-lookup-local
(p-assign (ident "retreat")))
(e-record
(fields
(field (name "x")
(e-num (value "7")))
(field (name "y")
(e-num (value "3"))))))
(e-record
(fields
(field (name "x")
(e-num (value "7")))
(field (name "y")
(e-num (value "2")))))))
(s-expect
(e-binop (op "eq")
(e-call
(e-lookup-local
(p-assign (ident "advance")))
(e-call
(e-lookup-local
(p-assign (ident "retreat")))
(e-record
(fields
(field (name "x")
(e-num (value "0")))
(field (name "y")
(e-num (value "0")))))))
(e-record
(fields
(field (name "x")
(e-num (value "0")))
(field (name "y")
(e-num (value "0"))))))))
~~~
# TYPES
~~~clojure
(inferred-types
(defs
(patt (type "Robot -> Robot"))
(patt (type "Robot -> Robot")))
(type_decls
(alias (type "Robot")
(ty-header (name "Robot"))))
(expressions
(expr (type "Robot -> Robot"))
(expr (type "Robot -> Robot"))))
~~~

View file

@ -0,0 +1,411 @@
# META
~~~ini
description=Robot simulator with I64 coordinates and record updates
type=snippet
~~~
# SOURCE
~~~roc
Robot : { x : I64, y : I64 }
advance_y : Robot -> Robot
advance_y = |robot| { ..robot, y: robot.y + 1 }
retreat_y : Robot -> Robot
retreat_y = |robot| { ..robot, y: robot.y - 1 }
advance_x : Robot -> Robot
advance_x = |robot| { ..robot, x: robot.x + 1 }
retreat_x : Robot -> Robot
retreat_x = |robot| { ..robot, x: robot.x - 1 }
expect advance_y({ x: 0, y: 0 }) == { x: 0, y: 1 }
expect retreat_y({ x: 0, y: 0 }) == { x: 0, y: -1 }
expect advance_x({ x: 0, y: 0 }) == { x: 1, y: 0 }
expect retreat_x({ x: 0, y: 0 }) == { x: -1, y: 0 }
expect advance_y(retreat_y({ x: 5, y: 5 })) == { x: 5, y: 5 }
~~~
# EXPECTED
NIL
# PROBLEMS
NIL
# TOKENS
~~~zig
UpperIdent,OpColon,OpenCurly,LowerIdent,OpColon,UpperIdent,Comma,LowerIdent,OpColon,UpperIdent,CloseCurly,
LowerIdent,OpColon,UpperIdent,OpArrow,UpperIdent,
LowerIdent,OpAssign,OpBar,LowerIdent,OpBar,OpenCurly,DoubleDot,LowerIdent,Comma,LowerIdent,OpColon,LowerIdent,NoSpaceDotLowerIdent,OpPlus,Int,CloseCurly,
LowerIdent,OpColon,UpperIdent,OpArrow,UpperIdent,
LowerIdent,OpAssign,OpBar,LowerIdent,OpBar,OpenCurly,DoubleDot,LowerIdent,Comma,LowerIdent,OpColon,LowerIdent,NoSpaceDotLowerIdent,OpBinaryMinus,Int,CloseCurly,
LowerIdent,OpColon,UpperIdent,OpArrow,UpperIdent,
LowerIdent,OpAssign,OpBar,LowerIdent,OpBar,OpenCurly,DoubleDot,LowerIdent,Comma,LowerIdent,OpColon,LowerIdent,NoSpaceDotLowerIdent,OpPlus,Int,CloseCurly,
LowerIdent,OpColon,UpperIdent,OpArrow,UpperIdent,
LowerIdent,OpAssign,OpBar,LowerIdent,OpBar,OpenCurly,DoubleDot,LowerIdent,Comma,LowerIdent,OpColon,LowerIdent,NoSpaceDotLowerIdent,OpBinaryMinus,Int,CloseCurly,
KwExpect,LowerIdent,NoSpaceOpenRound,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,CloseRound,OpEquals,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,
KwExpect,LowerIdent,NoSpaceOpenRound,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,CloseRound,OpEquals,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,
KwExpect,LowerIdent,NoSpaceOpenRound,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,CloseRound,OpEquals,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,
KwExpect,LowerIdent,NoSpaceOpenRound,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,CloseRound,OpEquals,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,
KwExpect,LowerIdent,NoSpaceOpenRound,LowerIdent,NoSpaceOpenRound,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,CloseRound,CloseRound,OpEquals,OpenCurly,LowerIdent,OpColon,Int,Comma,LowerIdent,OpColon,Int,CloseCurly,
EndOfFile,
~~~
# PARSE
~~~clojure
(file
(type-module)
(statements
(s-type-decl
(header (name "Robot")
(args))
(ty-record
(anno-record-field (name "x")
(ty (name "I64")))
(anno-record-field (name "y")
(ty (name "I64")))))
(s-type-anno (name "advance_y")
(ty-fn
(ty (name "Robot"))
(ty (name "Robot"))))
(s-decl
(p-ident (raw "advance_y"))
(e-lambda
(args
(p-ident (raw "robot")))
(e-record
(ext
(e-ident (raw "robot")))
(field (field "y")
(e-binop (op "+")
(e-field-access
(e-ident (raw "robot"))
(e-ident (raw "y")))
(e-int (raw "1")))))))
(s-type-anno (name "retreat_y")
(ty-fn
(ty (name "Robot"))
(ty (name "Robot"))))
(s-decl
(p-ident (raw "retreat_y"))
(e-lambda
(args
(p-ident (raw "robot")))
(e-record
(ext
(e-ident (raw "robot")))
(field (field "y")
(e-binop (op "-")
(e-field-access
(e-ident (raw "robot"))
(e-ident (raw "y")))
(e-int (raw "1")))))))
(s-type-anno (name "advance_x")
(ty-fn
(ty (name "Robot"))
(ty (name "Robot"))))
(s-decl
(p-ident (raw "advance_x"))
(e-lambda
(args
(p-ident (raw "robot")))
(e-record
(ext
(e-ident (raw "robot")))
(field (field "x")
(e-binop (op "+")
(e-field-access
(e-ident (raw "robot"))
(e-ident (raw "x")))
(e-int (raw "1")))))))
(s-type-anno (name "retreat_x")
(ty-fn
(ty (name "Robot"))
(ty (name "Robot"))))
(s-decl
(p-ident (raw "retreat_x"))
(e-lambda
(args
(p-ident (raw "robot")))
(e-record
(ext
(e-ident (raw "robot")))
(field (field "x")
(e-binop (op "-")
(e-field-access
(e-ident (raw "robot"))
(e-ident (raw "x")))
(e-int (raw "1")))))))
(s-expect
(e-binop (op "==")
(e-apply
(e-ident (raw "advance_y"))
(e-record
(field (field "x")
(e-int (raw "0")))
(field (field "y")
(e-int (raw "0")))))
(e-record
(field (field "x")
(e-int (raw "0")))
(field (field "y")
(e-int (raw "1"))))))
(s-expect
(e-binop (op "==")
(e-apply
(e-ident (raw "retreat_y"))
(e-record
(field (field "x")
(e-int (raw "0")))
(field (field "y")
(e-int (raw "0")))))
(e-record
(field (field "x")
(e-int (raw "0")))
(field (field "y")
(e-int (raw "-1"))))))
(s-expect
(e-binop (op "==")
(e-apply
(e-ident (raw "advance_x"))
(e-record
(field (field "x")
(e-int (raw "0")))
(field (field "y")
(e-int (raw "0")))))
(e-record
(field (field "x")
(e-int (raw "1")))
(field (field "y")
(e-int (raw "0"))))))
(s-expect
(e-binop (op "==")
(e-apply
(e-ident (raw "retreat_x"))
(e-record
(field (field "x")
(e-int (raw "0")))
(field (field "y")
(e-int (raw "0")))))
(e-record
(field (field "x")
(e-int (raw "-1")))
(field (field "y")
(e-int (raw "0"))))))
(s-expect
(e-binop (op "==")
(e-apply
(e-ident (raw "advance_y"))
(e-apply
(e-ident (raw "retreat_y"))
(e-record
(field (field "x")
(e-int (raw "5")))
(field (field "y")
(e-int (raw "5"))))))
(e-record
(field (field "x")
(e-int (raw "5")))
(field (field "y")
(e-int (raw "5"))))))))
~~~
# FORMATTED
~~~roc
NO CHANGE
~~~
# CANONICALIZE
~~~clojure
(can-ir
(d-let
(p-assign (ident "advance_y"))
(e-lambda
(args
(p-assign (ident "robot")))
(e-record
(ext
(e-lookup-local
(p-assign (ident "robot"))))
(fields
(field (name "y")
(e-binop (op "add")
(e-dot-access (field "y")
(receiver
(e-lookup-local
(p-assign (ident "robot")))))
(e-num (value "1")))))))
(annotation
(ty-fn (effectful false)
(ty-lookup (name "Robot") (local))
(ty-lookup (name "Robot") (local)))))
(d-let
(p-assign (ident "retreat_y"))
(e-lambda
(args
(p-assign (ident "robot")))
(e-record
(ext
(e-lookup-local
(p-assign (ident "robot"))))
(fields
(field (name "y")
(e-binop (op "sub")
(e-dot-access (field "y")
(receiver
(e-lookup-local
(p-assign (ident "robot")))))
(e-num (value "1")))))))
(annotation
(ty-fn (effectful false)
(ty-lookup (name "Robot") (local))
(ty-lookup (name "Robot") (local)))))
(d-let
(p-assign (ident "advance_x"))
(e-lambda
(args
(p-assign (ident "robot")))
(e-record
(ext
(e-lookup-local
(p-assign (ident "robot"))))
(fields
(field (name "x")
(e-binop (op "add")
(e-dot-access (field "x")
(receiver
(e-lookup-local
(p-assign (ident "robot")))))
(e-num (value "1")))))))
(annotation
(ty-fn (effectful false)
(ty-lookup (name "Robot") (local))
(ty-lookup (name "Robot") (local)))))
(d-let
(p-assign (ident "retreat_x"))
(e-lambda
(args
(p-assign (ident "robot")))
(e-record
(ext
(e-lookup-local
(p-assign (ident "robot"))))
(fields
(field (name "x")
(e-binop (op "sub")
(e-dot-access (field "x")
(receiver
(e-lookup-local
(p-assign (ident "robot")))))
(e-num (value "1")))))))
(annotation
(ty-fn (effectful false)
(ty-lookup (name "Robot") (local))
(ty-lookup (name "Robot") (local)))))
(s-alias-decl
(ty-header (name "Robot"))
(ty-record
(field (field "x")
(ty-lookup (name "I64") (builtin)))
(field (field "y")
(ty-lookup (name "I64") (builtin)))))
(s-expect
(e-binop (op "eq")
(e-call
(e-lookup-local
(p-assign (ident "advance_y")))
(e-record
(fields
(field (name "x")
(e-num (value "0")))
(field (name "y")
(e-num (value "0"))))))
(e-record
(fields
(field (name "x")
(e-num (value "0")))
(field (name "y")
(e-num (value "1")))))))
(s-expect
(e-binop (op "eq")
(e-call
(e-lookup-local
(p-assign (ident "retreat_y")))
(e-record
(fields
(field (name "x")
(e-num (value "0")))
(field (name "y")
(e-num (value "0"))))))
(e-record
(fields
(field (name "x")
(e-num (value "0")))
(field (name "y")
(e-num (value "-1")))))))
(s-expect
(e-binop (op "eq")
(e-call
(e-lookup-local
(p-assign (ident "advance_x")))
(e-record
(fields
(field (name "x")
(e-num (value "0")))
(field (name "y")
(e-num (value "0"))))))
(e-record
(fields
(field (name "x")
(e-num (value "1")))
(field (name "y")
(e-num (value "0")))))))
(s-expect
(e-binop (op "eq")
(e-call
(e-lookup-local
(p-assign (ident "retreat_x")))
(e-record
(fields
(field (name "x")
(e-num (value "0")))
(field (name "y")
(e-num (value "0"))))))
(e-record
(fields
(field (name "x")
(e-num (value "-1")))
(field (name "y")
(e-num (value "0")))))))
(s-expect
(e-binop (op "eq")
(e-call
(e-lookup-local
(p-assign (ident "advance_y")))
(e-call
(e-lookup-local
(p-assign (ident "retreat_y")))
(e-record
(fields
(field (name "x")
(e-num (value "5")))
(field (name "y")
(e-num (value "5")))))))
(e-record
(fields
(field (name "x")
(e-num (value "5")))
(field (name "y")
(e-num (value "5"))))))))
~~~
# TYPES
~~~clojure
(inferred-types
(defs
(patt (type "Robot -> Robot"))
(patt (type "Robot -> Robot"))
(patt (type "Robot -> Robot"))
(patt (type "Robot -> Robot")))
(type_decls
(alias (type "Robot")
(ty-header (name "Robot"))))
(expressions
(expr (type "Robot -> Robot"))
(expr (type "Robot -> Robot"))
(expr (type "Robot -> Robot"))
(expr (type "Robot -> Robot"))))
~~~

View file

@ -0,0 +1,86 @@
# META
~~~ini
description=Test str.to_utf8() method call syntax
type=snippet
~~~
# SOURCE
~~~roc
bytes : List(U8)
bytes = "hello".to_utf8()
expect bytes == [104, 101, 108, 108, 111]
~~~
# EXPECTED
NIL
# PROBLEMS
NIL
# TOKENS
~~~zig
LowerIdent,OpColon,UpperIdent,NoSpaceOpenRound,UpperIdent,CloseRound,
LowerIdent,OpAssign,StringStart,StringPart,StringEnd,NoSpaceDotLowerIdent,NoSpaceOpenRound,CloseRound,
KwExpect,LowerIdent,OpEquals,OpenSquare,Int,Comma,Int,Comma,Int,Comma,Int,Comma,Int,CloseSquare,
EndOfFile,
~~~
# PARSE
~~~clojure
(file
(type-module)
(statements
(s-type-anno (name "bytes")
(ty-apply
(ty (name "List"))
(ty (name "U8"))))
(s-decl
(p-ident (raw "bytes"))
(e-field-access
(e-string
(e-string-part (raw "hello")))
(e-apply
(e-ident (raw "to_utf8")))))
(s-expect
(e-binop (op "==")
(e-ident (raw "bytes"))
(e-list
(e-int (raw "104"))
(e-int (raw "101"))
(e-int (raw "108"))
(e-int (raw "108"))
(e-int (raw "111")))))))
~~~
# FORMATTED
~~~roc
NO CHANGE
~~~
# CANONICALIZE
~~~clojure
(can-ir
(d-let
(p-assign (ident "bytes"))
(e-dot-access (field "to_utf8")
(receiver
(e-string
(e-literal (string "hello"))))
(args))
(annotation
(ty-apply (name "List") (builtin)
(ty-lookup (name "U8") (builtin)))))
(s-expect
(e-binop (op "eq")
(e-lookup-local
(p-assign (ident "bytes")))
(e-list
(elems
(e-num (value "104"))
(e-num (value "101"))
(e-num (value "108"))
(e-num (value "108"))
(e-num (value "111")))))))
~~~
# TYPES
~~~clojure
(inferred-types
(defs
(patt (type "List(U8)")))
(expressions
(expr (type "List(U8)"))))
~~~