#lang typed/racket/base
(require "assemble-helpers.rkt"
"../compiler/il-structs.rkt"
"../compiler/lexical-structs.rkt"
"../parameters.rkt"
racket/string)
(provide assemble-op-statement)
(: assemble-op-statement (PrimitiveCommand -> String))
(define (assemble-op-statement op)
(cond
[(CheckToplevelBound!? op)
(format "if (MACHINE.env[MACHINE.env.length - 1 - ~a][~a] === undefined) { RUNTIME.raiseUnboundToplevelError(MACHINE.env[MACHINE.env.length - 1 - ~a].names[~a]); }"
(CheckToplevelBound!-depth op)
(CheckToplevelBound!-pos op)
(CheckToplevelBound!-depth op)
(CheckToplevelBound!-pos op))]
[(CheckClosureArity!? op)
(format #<<EOF
if (! (MACHINE.proc instanceof RUNTIME.Closure)) {
RUNTIME.raiseOperatorIsNotClosure(MACHINE, MACHINE.proc) }
if (! RUNTIME.isArityMatching(MACHINE.proc.racketArity, ~a)) {
RUNTIME.raiseArityMismatchError(MACHINE,
MACHINE.proc,
MACHINE.proc.racketArity,
~a) }
EOF
(assemble-oparg (CheckClosureArity!-num-args op))
(assemble-oparg (CheckClosureArity!-num-args op)))]
[(CheckPrimitiveArity!? op)
(format #<<EOF
if (! (typeof(MACHINE.proc) === 'function')) {
RUNTIME.raiseOperatorIsNotPrimitiveProcedure(MACHINE, MACHINE.proc) }
if (! RUNTIME.isArityMatching(MACHINE.proc.racketArity, ~a)) {
RUNTIME.raiseArityMismatchError(MACHINE,
MACHINE.proc,
MACHINE.proc.racketArity,
~a) }
EOF
(assemble-oparg (CheckPrimitiveArity!-num-args op))
(assemble-oparg (CheckPrimitiveArity!-num-args op)))]
[(ExtendEnvironment/Prefix!? op)
(let: ([names : (Listof (U Symbol False GlobalBucket ModuleVariable)) (ExtendEnvironment/Prefix!-names op)])
(format "MACHINE.env.push([~a]); MACHINE.env[MACHINE.env.length-1].names = [~a];"
(string-join (map
(lambda: ([n : (U Symbol False GlobalBucket ModuleVariable)])
(cond [(symbol? n)
(format "MACHINE.params.currentNamespace[~s] || MACHINE.primitives[~s]"
(symbol->string n)
(symbol->string n))]
[(eq? n #f)
"false"]
[(GlobalBucket? n)
(format "MACHINE.primitives[~s]"
(symbol->string (GlobalBucket-name n)))]
[(ModuleVariable? n)
(cond
[((current-kernel-module-locator?)
(ModuleVariable-module-name n))
(format "MACHINE.primitives[~s]"
(symbol->string (ModuleVariable-name n)))]
[else
(format "MACHINE.modules[~s].namespace[~s]"
(symbol->string
(ModuleLocator-name
(ModuleVariable-module-name n)))
(symbol->string (ModuleVariable-name n)))])]))
names)
",")
(string-join (map
(lambda: ([n : (U Symbol False GlobalBucket ModuleVariable)])
(cond
[(symbol? n)
(format "~s" (symbol->string n))]
[(eq? n #f)
"false"]
[(GlobalBucket? n)
(format "~s" (symbol->string (GlobalBucket-name n)))]
[(ModuleVariable? n)
(format "~s" (symbol->string (ModuleVariable-name n)))]))
names)
",")))]
[(InstallClosureValues!? op)
"MACHINE.env.splice.apply(MACHINE.env, [MACHINE.env.length, 0].concat(MACHINE.proc.closedVals));"]
[(RestoreEnvironment!? op)
"MACHINE.env = MACHINE.env[MACHINE.env.length - 2].slice(0);"]
[(RestoreControl!? op)
(format "MACHINE.restoreControl(~a);"
(let: ([tag : (U DefaultContinuationPromptTag OpArg)
(RestoreControl!-tag op)])
(cond
[(DefaultContinuationPromptTag? tag)
(assemble-default-continuation-prompt-tag)]
[(OpArg? tag)
(assemble-oparg tag)])))]
[(FixClosureShellMap!? op)
(format "MACHINE.env[MACHINE.env.length - 1 - ~a].closedVals = [~a]"
(FixClosureShellMap!-depth op)
(string-join (map
assemble-env-reference/closure-capture
(reverse (FixClosureShellMap!-closed-vals op)))
", "))]
[(SetFrameCallee!? op)
(format "MACHINE.control[MACHINE.control.length-1].proc = ~a;"
(assemble-oparg (SetFrameCallee!-proc op)))]
[(SpliceListIntoStack!? op)
(format "MACHINE.spliceListIntoStack(~a);"
(assemble-oparg (SpliceListIntoStack!-depth op)))]
[(UnspliceRestFromStack!? op)
(format "MACHINE.unspliceRestFromStack(~a, ~a);"
(assemble-oparg (UnspliceRestFromStack!-depth op))
(assemble-oparg (UnspliceRestFromStack!-length op)))]
[(InstallContinuationMarkEntry!? op)
(string-append "RUNTIME.installContinuationMarkEntry(MACHINE,"
"MACHINE.control[MACHINE.control.length-1].pendingContinuationMarkKey,"
"MACHINE.val);")]
[(RaiseContextExpectedValuesError!? op)
(format "RUNTIME.raiseContextExpectedValuesError(MACHINE, ~a);"
(RaiseContextExpectedValuesError!-expected op))]
[(RaiseArityMismatchError!? op)
(format "RUNTIME.raiseArityMismatchError(MACHINE, ~a, ~a, ~a);"
(assemble-oparg (RaiseArityMismatchError!-proc op))
(assemble-arity (RaiseArityMismatchError!-expected op))
(assemble-oparg (RaiseArityMismatchError!-received op)))]
[(RaiseOperatorApplicationError!? op)
(format "RUNTIME.raiseOperatorApplicationError(MACHINE, ~a);"
(assemble-oparg (RaiseOperatorApplicationError!-operator op)))]
[(RaiseUnimplementedPrimitiveError!? op)
(format "RUNTIME.raiseUnimplementedPrimitiveError(MACHINE, ~s);"
(symbol->string (RaiseUnimplementedPrimitiveError!-name op)))]
[(InstallModuleEntry!? op)
(format "MACHINE.modules[~s]=new RUNTIME.ModuleRecord(~s, ~a);"
(symbol->string (ModuleLocator-name (InstallModuleEntry!-path op)))
(symbol->string (InstallModuleEntry!-name op))
(assemble-label (make-Label (InstallModuleEntry!-entry-point op))))]
[(MarkModuleInvoked!? op)
(format "MACHINE.modules[~s].isInvoked = true;"
(symbol->string (ModuleLocator-name (MarkModuleInvoked!-path op))))]
[(AliasModuleAsMain!? op)
(format "MACHINE.mainModules.push(MACHINE.modules[~s]);"
(symbol->string (ModuleLocator-name (AliasModuleAsMain!-from op))))]
[(FinalizeModuleInvokation!? op)
(format "MACHINE.modules[~s].finalizeModuleInvokation();"
(symbol->string
(ModuleLocator-name (FinalizeModuleInvokation!-path op))))]))