compile-argv-hook := ();
compile-include-argv := λ. if compile-argv-hook () (set compile-argv-hook (compile-argv-hook (
\t 'pop \s '%r10 \n # put argc in '%r10
\t 'mov \s '$argv, \s '%r9 \n
\t 'movq \s '$0, \s '0 \[ '%r9 \] \n
\t 'movq \s '$0, \s '8 \[ '%r9 \] \n
'before_main_argv: \n
\t 'cmp \s '$0, \s '%r10 \n
\t 'je \s 'before_main_end \n
\t 'pop \s '%r12 \n #this = argv[i]
\t 'mov \s '$0, \s '%r13 \n
(close()) #r8 is argv[i]
\t 'mov \s '%r8, \s '0 \[ '%r9 \] \n #set t.head = argv[i]
\t 'mov \s '$0, \s '%r12 \n
\t 'mov \s '$0, \s '%r13 \n
(close())
\t 'mov \s '%r8, \s '8 \[ '%r9 \] \n #set t.tail = ()
\t 'mov \s '%r8, \s '%r9 \n #set t = t.tail
\t 'dec \s '%r10 \n #dec argc
\t 'jmp \s 'before_main_argv \n
'before_main_end: \n
)));
compile-append := λoutput_e gctx e . (tail(
(set e (compile-expr( gctx e (expr::get-offset output_e) Unused )))
(Expr(
((expr::get-frame output_e) (expr::get-frame e))
((expr::get-prog output_e) (expr::get-prog e))
((expr::get-unframe output_e) (expr::get-unframe e))
((expr::get-text output_e) (expr::get-text e))
((expr::get-data output_e) (expr::get-data e))
(expr::get-context e)
(expr::get-offset e)
))
));
compile-expr := λctx e offset used . (tail(
(assert-typeof( 'compile-expr-dynamic::ctx ctx Context ))
(if config-strict (compile-expr-strict( ctx e (if offset offset 0) used ))
(compile-expr-dynamic( ctx e offset used )))
));
compile-expr-dynamic := λctx e offset used . (tail(
(assert-typeof( 'compile-expr-dynamic::ctx ctx Context ))
(local e1)
(local e2)
(local e3)
(local prog)
(local tail_safe)
(local return)
(set return (match e (
()
( (Variable '$_) (tail(
()
(Expr( () () () () () ctx offset ))
)))
( (Variable 'argv) (tail(
(compile-include-argv())
(set prog (prog ( \t 'mov \s '$argv, \s '%r8 \n )))
(set prog (prog ( \t 'mov \s '0 \[ '%r8 \] , '%r12 \n )))
(set prog (prog ( \t 'mov \s '8 \[ '%r8 \] , '%r13 \n )))
(Expr( () prog () () () ctx offset ))
)))
( (Variable vname) (tail(
()
(Expr( () (get-local(ctx vname)) () () () ctx offset ))
)))
( (App( (App( (Literal :) (Literal lval) )) ltype )) (tail(
()
(fail (TODO CompileExpressionLiteral e))
)))
( (App( (App( (Literal :) inner_expr )) (Literal ltype) )) (tail(
()
(compile-expr( ctx inner_expr offset used ))
)))
( (App ((Variable 'local) (Variable fname))) (tail(
(set e1 (declare-local(ctx fname offset)))
(Expr( (expr::get-frame e1) ((yield-nil()) (expr::get-prog e1)) (expr::get-unframe e1) (expr::get-text e1) (expr::get-data e1) (expr::get-context e1) (expr::get-offset e1) ))
)))
( (App ((Variable 'gensym-label) (Variable fname))) (tail(
(set ctx (context::bind( ctx fname (Label (uuid())) )))
(Expr( () () () () () ctx offset ))
)))
( (App( (Lambda( (Variable lhs) rhs )) bind )) (tail(
(set e1 (declare-local(ctx lhs offset)))
(set e2 (compile-expr((expr::get-context e1) bind (expr::get-offset e1) Used)))
(set e3 (compile-expr((expr::get-context e2) rhs (expr::get-offset e2) Used)))
(set prog ( prog (yield-nil()) (expr::get-prog e1) ))
(set prog ( prog (expr::get-prog e2) (set-local((expr::get-context e2) lhs)) ))
(set prog ( prog (expr::get-prog e3) ))
(Expr(
((expr::get-frame e1) (expr::get-frame e2) (expr::get-frame e3))
prog
((expr::get-unframe e1) (expr::get-unframe e2) (expr::get-unframe e3))
((expr::get-text e1) (expr::get-text e2) (expr::get-text e3))
((expr::get-data e1) (expr::get-data e2) (expr::get-data e3))
(expr::get-context e3) (expr::get-offset e3)
))
)))
( (App( (App( (Variable 'set) (Variable vname) )) x )) (tail(
(set e1 (compile-expr(ctx x offset Used)))
(set prog ((expr::get-prog e1) (set-local(ctx vname))))
(Expr( (expr::get-frame e1) prog (expr::get-unframe e1) (expr::get-text e1) (expr::get-data e1) (expr::get-context e1) (expr::get-offset e1) ))
)))
( (App( (App( (Variable 'while) c )) d )) (tail(
(set e1 (compile-expr(ctx c offset Used)))
(set e2 (compile-expr((expr::get-context e1) d (expr::get-offset e1) Unused)))
(local label_while_start)
(set label_while_start (uuid()))
(local label_while_end)
(set label_while_end (uuid()))
(set prog (prog (label_while_start ': \n)))
(set prog (prog (expr::get-prog e1)))
(set prog (prog (\t 'cmp \s '$0, \s '%r12 \n)))
(set prog (prog (\t 'je \s label_while_end \n)))
(set prog (prog (expr::get-prog e2)))
(set prog (prog (\t 'jmp \s label_while_start \n)))
(set prog (prog (label_while_end ': \n)))
(set tail_safe True)
(Expr( ((expr::get-frame e1) (expr::get-frame e2)) prog ((expr::get-unframe e1) (expr::get-unframe e2)) ((expr::get-text e1) (expr::get-text e2)) ((expr::get-data e1) (expr::get-data e2)) (expr::get-context e2) (expr::get-offset e2) ))
)))
( (App( (Variable 'exit) (Literal _) )) (tail(
(set tail_safe True)
(set prog (
\t 'mov \s '$60, \s '%rax \n
\t 'mov \s '$1 , \s '%rdi \n
\t 'syscall \n
))
(Expr( () prog () () () ctx offset ))
)))
( (App( (Variable 'eq) (App( l r )) )) (tail(
(set e1 (compile-expr(ctx l offset Used)))
(set e2 (compile-expr(ctx r offset Used)))
(local eq-yield-end)
(set eq-yield-end (uuid()))
(local eq-yield-false)
(set eq-yield-false (uuid()))
(set prog (
(expr::get-prog e1)
\t 'cmp \s '$0, \s '%r12 \n
\t 'je \s eq-yield-false \n
\t 'cmp \s '$0, \s '%r13 \n
\t 'jne \s eq-yield-false \n
\t 'push \s '%r12 \n
(expr::get-prog e2)
\t 'cmp \s '$0, \s '%r12 \n
\t 'je \s eq-yield-false \n
\t 'cmp \s '$0, \s '%r13 \n
\t 'jne \s eq-yield-false \n
\t 'mov \s '%r12 , \s '%rax \n
\t 'pop \s '%rbx \n
\t 'call \s 'streq \n
\t 'jmp \s eq-yield-end \n
eq-yield-false ': \n
\t 'mov \s '$0 , \s '%r12 \n
\t 'mov \s '$0 , \s '%r13 \n
eq-yield-end ': \n
))
(Expr(
((expr::get-frame e1) (expr::get-frame e2))
prog
((expr::get-unframe e1) (expr::get-unframe e2))
((expr::get-text e1) (expr::get-text e2))
((expr::get-data e1) (expr::get-data e2))
ctx
offset
))
)))
( (App( (Variable 'is) (App( l r )) )) (tail(
(set e1 (compile-expr(ctx l offset Used)))
(set e2 (compile-expr(ctx r offset Used)))
(local is-yield-end)
(set is-yield-end (uuid()))
(local is-yield-false)
(set is-yield-false (uuid()))
(set prog (
(expr::get-prog e1)
\t 'push \s '%r12 \n
\t 'push \s '%r13 \n
(expr::get-prog e2)
\t 'pop \s '%r15 \n
\t 'pop \s '%r14 \n
\t 'cmp \s '%r14, \s '%r12 \n
\t 'jne \s is-yield-false \n
\t 'cmp \s '%r15, \s '%r13 \n
\t 'jne \s is-yield-false \n
\t 'mov \s '$true, \s '%r12 \n
\t 'mov \s '$0, \s '%r13 \n
\t 'jmp \s is-yield-end \n
is-yield-false ': \n
\t 'mov \s '$0 , \s '%r12 \n
\t 'mov \s '$0 , \s '%r13 \n
is-yield-end ': \n
))
(Expr(
((expr::get-frame e1) (expr::get-frame e2))
prog
((expr::get-unframe e1) (expr::get-unframe e2))
((expr::get-text e1) (expr::get-text e2))
((expr::get-data e1) (expr::get-data e2))
ctx
offset
))
)))
( (App( (App( (App( (Variable 'if) c )) t )) f )) (tail(
(set e1 (compile-expr(ctx c offset Used)))
(set e2 (compile-expr( (expr::get-context e1) t (expr::get-offset e1) Used )))
(set e3 (compile-expr( (expr::get-context e2) f (expr::get-offset e2) Used )))
(local label_if_true)
(set label_if_true (uuid()))
(local label_if_end)
(set label_if_end (uuid()))
(set prog (prog (expr::get-prog e1)))
(set prog (prog ( \t 'cmp \s '$0, '%r12 \n )))
(set prog (prog ( \t 'jne \s label_if_true \n )))
(set prog (prog ( \t 'cmp \s '$0, '%r13 \n )))
(set prog (prog ( \t 'jne \s label_if_true \n )))
(set prog (prog (expr::get-prog e3)))
(set prog (prog ( \t 'jmp \s label_if_end \n )))
(set prog (prog ( label_if_true ': \n )))
(set prog (prog (expr::get-prog e2)))
(set prog (prog ( label_if_end ': \n )))
(Expr(
((expr::get-frame e1) (expr::get-frame e2) (expr::get-frame e3))
prog
((expr::get-unframe e1) (expr::get-unframe e2) (expr::get-unframe e3))
((expr::get-text e1) (expr::get-text e2) (expr::get-text e3))
((expr::get-data e1) (expr::get-data e2) (expr::get-data e3))
(expr::get-context e3)
(expr::get-offset e3)
))
)))
( (App( (App( (Variable 'match) t )) p )) (tail(
(set e1 (compile-expr(ctx t offset Used)))
(set e2 (yield-patterns((expr::get-context e1) p (expr::get-offset e1))))
(local label_skip)
(set label_skip (uuid()))
(set prog ((expr::get-prog e1) (expr::get-prog e2)))
(set prog (prog ( \t 'cmp \s '$0, \s '%r14 \n )))
(set prog (prog ( \t 'jne \s label_skip \n )))
(set prog (prog (yield-nil())))
(set prog (prog ( label_skip ': \n )))
(Expr(
((expr::get-frame e1) (expr::get-frame e2))
prog
((expr::get-unframe e1) (expr::get-unframe e2))
((expr::get-text e1) (expr::get-text e2))
((expr::get-data e1) (expr::get-data e2))
(expr::get-context e2)
(expr::get-offset e2)
))
)))
( (App ((Variable fname) arg)) (tail(
()
(apply-calling-convention-s( ctx e fname arg offset used ))
)))
( (Literal l) (tail(
()
(yield-atom (ctx l offset))
)))
( Nil (tail(
(set prog (prog ( \t 'mov \s '$0 , '%r12 \n )))
(set prog (prog ( \t 'mov \s '$0 , '%r13 \n )))
(set tail_safe True)
(Expr( () prog () () () ctx offset ))
)))
( (App (l r)) (tail(
(set tail_safe True)
(yield-cons(ctx l r e offset used))
)))
( (GlobalVariable mangled-name) (tail(
(set prog (
\t 'mov \s '$ mangled-name , \s '%r15 \n
\t 'mov \s '0 \[ '%r15 \] , \s '%r12 \n
\t 'mov \s '8 \[ '%r15 \] , \s '%r13 \n
))
(Expr( () prog () () () ctx offset ))
)))
( u (fail (UnrecognizedExpression u)) )
)))
(if tail_safe return (tail(
()
(if (eq(used Tail)) (tail(
(set prog (expr::get-prog return))
(set prog (prog (\t 'call \s 'tail \n)))
(Expr( (expr::get-frame return) prog (expr::get-unframe return) (expr::get-text return) (expr::get-data return) (expr::get-context return) (expr::get-offset return) ))
)) (
return
))
)))
));
define-calling-convention-s := λ ctx fname lmb . (tail(
()
(match lmb (
()
( (Lambda( lhs rhs )) (tail(
(local e1)
(local e2)
(local text)
(set e1 (destructure-args(ctx lhs ())))
(set e2 (compile-expr((expr::get-context e1) rhs (expr::get-offset e1) Used)))
(set text ( text (mangle-identifier( fname (typecheck-lookup lmb) )) ': \n ))
(set text ( text (enter-function()) ))
(set text ( text (expr::get-frame e1) (expr::get-frame e2) ))
(set text ( text (expr::get-prog e1) (expr::get-prog e2) ))
(set text ( text (exit-function()) ))
(set text ( text (expr::get-text e1) (expr::get-text e2) ))
(Expr(
() () () text ( (expr::get-data e1) (expr::get-data e2) ) () ()
))
)))
))
));
apply-calling-convention-s := λ ctx e fname arg offset used . (tail(
(local e1)
(local prog)
(if (is-builtin fname) (tail(
()
(if (eq(fname 'tail)) (tail(
(set e1 (compile-expr(ctx arg offset Tail)))
(Expr( (expr::get-frame e1) (expr::get-prog e1) (expr::get-unframe e1) (expr::get-text e1) (expr::get-data e1) (expr::get-context e1) (expr::get-offset e1) ))
)) (tail(
(set e1 (compile-expr(ctx arg offset Used)))
(set prog ((expr::get-prog e1) (\t 'call \s (label-case fname) \n)))
(Expr( (expr::get-frame e1) prog (expr::get-unframe e1) (expr::get-text e1) (expr::get-data e1) (expr::get-context e1) (expr::get-offset e1) ))
)))
)) (tail(
()
(match (get-maybe-function(ctx fname (typecheck-lookup arg))) (
()
( (GlobalFunction mangledname) (tail(
(set e1 (compile-expr(ctx arg offset Used)))
(set prog ((expr::get-prog e1) (\t 'call \s mangledname \n)))
(Expr( (expr::get-frame e1) prog (expr::get-unframe e1) (expr::get-text e1) (expr::get-data e1) (expr::get-context e1) (expr::get-offset e1) ))
)))
( () (
(fail (ReferenceToUndefinedVariable fname (typecheck-lookup arg)))
))
( v (tail(
()
(yield-cons(ctx v arg e offset Used))
)))
))
)))
));
get-local := λctx v . (tail(
()
(match (context::lookup( ctx v () )) (
()
( (Local( getter setter )) (
getter
))
( (GlobalVariable( body )) (
(
\t 'mov \s '$ (label-case v) , \s '%r15 \n
\t 'mov \s '0 \[ '%r15 \] , \s '%r12 \n
\t 'mov \s '8 \[ '%r15 \] , \s '%r13 \n
)
))
( () (
fail (ReferenceToUndefinedVariable v)
))
( u (
fail (UnexpectedLocal u)
))
))
));
set-local := λctx v . (tail(
()
(match (context::lookup( ctx v () )) (
()
( (Local( getter setter )) (
setter
))
( (GlobalVariable( body )) (
(
\t 'mov \s '$ (label-case v) , \s '%r15 \n
\t 'mov \s '%r12 , \s '0 \[ '%r15 \] \n
\t 'mov \s '%r13 , \s '8 \[ '%r15 \] \n
)
))
( () (
fail (AssignToUndefinedVariable v)
))
( u (
fail (UnexpectedLocal u)
))
))
));
get-maybe-function := λctx v arg_type . (
(match (context::lookup( ctx v () )) (
()
( (Local(getter setter)) (
(Variable v)
))
( (GlobalFunction( body )) (
(GlobalFunction( (mangle-identifier( v (typecheck-lookup body) )) ))
))
( (GlobalVariable( body )) (
(GlobalVariable( label-case v ))
))
(u (fail (UnexpectedFunction v u)))
))
);
declare-local := λctx vname offset . (tail(
(local frame_this)
(set frame_this (push-zero()))
(local refer)
(local eight)
(set eight (s2i 8))
(local sixteen)
(set sixteen (s2i 16))
(local set_this)
(set set_this (
\t 'mov \s '%r12, \s (
(i2s( (mul( (add( (mul( sixteen offset )) eight)) (dec(())) )) ))
) \[ '%rbp \] \n
\t 'mov \s '%r13, \s (
(i2s( (mul( (add( (mul( sixteen offset )) sixteen)) (dec(())) )) ))
) \[ '%rbp \] \n
))
(set refer (
\t 'mov \s (
(i2s( (mul( (add( (mul( sixteen offset )) eight)) (dec(())) )) ))
) \[ '%rbp \] , '%r12 \n
\t 'mov \s (
(i2s( (mul( (add( (mul( sixteen offset )) sixteen)) (dec(())) )) ))
) \[ '%rbp \] , '%r13 \n
))
(set ctx (context::bind( ctx vname (Local( refer set_this )) )))
(Expr(frame_this set_this () () () ctx (inc offset)))
));
destructure-args := λctx e offset . (match e (
()
( Nil (tail(
()
(Expr( () () () () () ctx offset ))
)))
( (App( (App( (Literal :) (Variable n) )) nt )) (tail(
()
(declare-local(ctx n offset))
)))
( (Variable n) (tail(
()
(declare-local(ctx n offset))
)))
( ( (App( h t )) ) (tail(
(local ta)
(set ta (destructure-args(ctx t offset)))
(set offset (expr::get-offset ta))
(set ctx (expr::get-context ta))
(local ha)
(set ha (destructure-args(ctx h offset)))
(set offset (expr::get-offset ha))
(set ctx (expr::get-context ha))
(local prog)
(set prog (prog (push-this()) ))
(set prog (prog (\t 'call \s 'tail \n) ))
(set prog (prog (expr::get-prog ta) ))
(set prog (prog (pop-this()) ))
(set prog (prog (\t 'call \s 'head \n) ))
(set prog (prog (expr::get-prog ha) ))
(Expr(
( (expr::get-frame ta) (expr::get-frame ha) )
prog
( (expr::get-unframe ta) (expr::get-unframe ha) )
() () ctx offset
))
)))
( _ (
(fail (InvalidFunctionParameters DidYouForgetToSeparateADotTokenInFunctionParam? e))
))
));
yield-cons-s := λctx l r ce offset used . (tail(
(local e1)
(local e2)
(local prog)
(local rused)
(match used (
()
( Used (tail(
(set e1 (compile-expr( ctx l offset Used )))
(set offset (expr::get-offset e1))
(set e2 (compile-expr( (expr::get-context e1) r (expr::get-offset e1) Used )))
(set offset (expr::get-offset e2))
(set prog (prog (expr::get-prog e1)))
(set prog (prog (push-this())))
(set prog (prog (expr::get-prog e2)))
(set prog (prog (close())))
(set prog (prog (pop-this())))
(set prog (prog (\t 'push \s '%r8 \n)))
(set prog (prog (close())))
(set prog (prog (\t 'mov \s '%r8, \s '%r12 \n)))
(set prog (prog (\t 'pop \s '%r13 \n)))
(Expr( ((expr::get-frame e1) (expr::get-frame e2)) prog ((expr::get-unframe e1) (expr::get-unframe e2)) ((expr::get-text e1) (expr::get-text e2)) ((expr::get-data e1) (expr::get-data e2)) (expr::get-context e2) (expr::get-offset e2) ))
)))
( _ (tail(
(set rused ( if (eq(used Tail)) Used Unused ))
(set e1 (compile-expr( ctx l offset Unused )))
(set e2 (compile-expr( (expr::get-context e1) r (expr::get-offset e1) rused )))
(Expr( ((expr::get-frame e1) (expr::get-frame e2)) ((expr::get-prog e1) (expr::get-prog e2)) ((expr::get-unframe e1) (expr::get-unframe e2)) ((expr::get-text e1) (expr::get-text e2)) ((expr::get-data e1) (expr::get-data e2)) (expr::get-context e2) (expr::get-offset e2) ))
)))
))
));
yield-cons := λctx l r ce offset used . (tail(
(local e1)
(local e2)
(yield-cons-s( ctx l r ce offset used ))
));
yield-atom-cache := ();
yield-atom := λctx a offset . (tail(
(local cache)
(set cache yield-atom-cache)
(local id)
(local data)
(while cache (tail(
(if (eq( (head (head cache)) a )) (
(set id (tail (head cache)))
) ())
(set cache (tail cache))
)))
(if id () (
(set id (uuid()))
(set data (id ': \n \t '.ascii \s " (escape-sequences a) " \n \t '.zero \s 1 \n))
(set yield-atom-cache ((a id) yield-atom-cache))
))
(Expr(
()
(\t 'mov \s '$ id , \s '%r12 \n # $_.$1 = 0, .atom
\t 'mov \s '$0, \s '%r13 \n # $_.$2 = 0, .head
)
()
()
data
ctx
offset
))
));
escape-sequences := λt . match t (
()
( () () )
( \\ \\\\ )
( \\: \: )
( \\o \o )
( \\n (\\ 'n))
( \\t \t )
( \\s \s )
( \\l \l )
( \\[ \[ )
( \\] \] )
( (l r) ( (escape-sequences l) (escape-sequences r) ) )
( s (tail(
(local c)
(local cs)
(local is_escape)
(while s (tail(
(set c (head-string s))
(set s (tail-string s))
(match c (
()
( " (
(set cs (cs \\ "))
(set is_escape ())
))
(\\ (
(if is_escape (
(set cs ( cs \\\\ ))
(set is_escape ())
) (set is_escape True))
))
(_ (
(if is_escape (
(match c (
()
( , (set cs (cs .)))
( _ (fail( InvalidEscapeCharacter (c s) )))
))
) (set cs (cs (clone-rope c))))
(set is_escape ())
))
))
)))
(clone-rope cs)
)))
);
yield-patterns := λctx p offset . match p (
()
( Nil (tail(
()
(Expr( () (\t 'mov \s '$0, \s '%r14 \n) () () () ctx offset ))
)))
( (App( prev (App( lhs rhs )) )) (tail(
(local e1)
(local e2)
(local e3)
(local prog)
(set e1 (yield-patterns(ctx prev offset)))
(set e2 (destructure-pattern-lhs((expr::get-context e1) lhs (expr::get-offset e1))))
(set e3 (compile-expr((expr::get-context e2) rhs (expr::get-offset e2) Used)))
(local label_skip)
(set label_skip (uuid()))
(set prog (prog (expr::get-prog e1)))
(set prog (prog (\t 'cmp \s '$0, \s '%r14 \n)))
(set prog (prog (\t 'jne \s label_skip \n)))
(set prog (prog (expr::get-prog e2)))
(set prog (prog (\t 'cmp \s '$0, \s '%r14 \n)))
(set prog (prog (\t 'je \s label_skip \n)))
(set prog (prog (expr::get-prog e3)))
(set prog (prog (\t 'mov \s '$1, \s '%r14 \n)))
(set prog (prog (label_skip ': \n)))
(Expr(
((expr::get-frame e1) (expr::get-frame e2) (expr::get-frame e3))
prog
((expr::get-unframe e1) (expr::get-unframe e2) (expr::get-unframe e3))
((expr::get-text e1) (expr::get-text e2) (expr::get-text e3))
((expr::get-data e1) (expr::get-data e2) (expr::get-data e3))
ctx
(expr::get-offset e3)
))
)))
( _ (
(fail (InvalidPatternsCase p))
))
);
destructure-pattern-lhs := λctx lhs offset . (tail(
(local e1)
(local e2)
(local prog)
(local label_skip)
(match lhs (
()
( (Variable '_) (tail(
()
(Expr( () (\t 'mov \s '$1, \s '%r14 \n) () () () ctx offset ))
)))
( (Variable v) (tail(
(set e1 (declare-local(ctx v offset)))
(Expr(
(expr::get-frame e1)
((expr::get-prog e1) \t 'mov \s '$1, \s '%r14 \n)
(expr::get-unframe e1)
(expr::get-text e1)
(expr::get-data e1)
(expr::get-context e1)
(expr::get-offset e1)
))
)))
( (Literal l) (tail(
(set e1 (yield-atom(ctx l offset)))
(set label_skip (uuid()))
(set prog (prog (push-this())))
(set prog (prog (\t 'cmp \s '$0, \s '%r12 \n)))
(set prog (prog (\t 'je \s label_skip \n)))
(set prog (prog (\t 'cmp \s '$0, \s '%r13 \n)))
(set prog (prog (\t 'jne \s label_skip \n)))
(set prog (prog (\t 'mov \s '%r12, \s '%rax \n)))
(set prog (prog (expr::get-prog e1)))
(set prog (prog (\t 'mov \s '%r12, \s '%rbx \n)))
(set prog (prog (\t 'call \s 'streq \n)))
(set prog (prog (\t 'cmp \s '$0, \s '%r12 \n)))
(set prog (prog (\t 'je \s label_skip \n)))
(set prog (prog (\t 'mov \s '$1, \s '%r14 \n)))
(set prog (prog (label_skip ': \n)))
(set prog (prog (pop-this())))
(Expr( (expr::get-frame e1) prog (expr::get-unframe e1) (expr::get-text e1) (expr::get-data e1) (expr::get-context e1) (expr::get-offset e1) ))
)))
( Nil (tail(
(set label_skip (uuid()))
(set prog (prog (\t 'cmp \s '$0, \s '%r12 \n)))
(set prog (prog (\t 'jne \s label_skip \n)))
(set prog (prog (\t 'cmp \s '$0, \s '%r13 \n)))
(set prog (prog (\t 'jne \s label_skip \n)))
(set prog (prog (\t 'mov \s '$1, \s '%r14 \n)))
(set prog (prog (label_skip ': \n)))
(Expr( () prog () () () ctx offset ))
)))
( (App( l r )) (tail(
(set e1 (destructure-pattern-lhs(ctx l offset)))
(set e2 (destructure-pattern-lhs((expr::get-context e1) r (expr::get-offset e1))))
(set label_skip (uuid()))
(set prog (prog (\t 'mov \s '$0, \s '%r14 \n)))
(set prog (prog (push-this())))
(set prog (prog (\t 'cmp \s '$0, \s '%r13 \n)))
(set prog (prog (\t 'je \s label_skip \n)))
(set prog (prog (inline-head())))
(set prog (prog (expr::get-prog e1)))
(set prog (prog (pop-this())))
(set prog (prog (push-this())))
(set prog (prog (\t 'cmp \s '$0, \s '%r14 \n)))
(set prog (prog (\t 'je \s label_skip \n)))
(set prog (prog (\t 'mov \s '$0, \s '%r14 \n)))
(set prog (prog (inline-tail())))
(set prog (prog (expr::get-prog e2)))
(set prog (prog (label_skip ': \n)))
(set prog (prog (pop-this())))
(Expr(
((expr::get-frame e1) (expr::get-frame e2))
prog
((expr::get-unframe e1) (expr::get-unframe e2))
((expr::get-text e1) (expr::get-text e2))
((expr::get-data e1) (expr::get-data e2))
(expr::get-context e2)
(expr::get-offset e2)
))
)))
(_ (fail (UnexpectedPattern lhs)))
))
));