diff options
| author | Marshall Lochbaum <mwlochbaum@gmail.com> | 2022-02-12 18:21:03 -0500 |
|---|---|---|
| committer | Marshall Lochbaum <mwlochbaum@gmail.com> | 2022-02-12 18:21:03 -0500 |
| commit | 901cafdfdb652a52a90af9b5c5a43c1572978f34 (patch) | |
| tree | 17f5edfebb6edb36eee47c5d2a7a80c47ed40602 /vm.bqn | |
| parent | ba4f32e4bbef5588c859a1ce63dd8933cc63f963 (diff) | |
Comment the rest of vm.bqn
Diffstat (limited to 'vm.bqn')
| -rw-r--r-- | vm.bqn | 39 |
1 files changed, 28 insertions, 11 deletions
@@ -12,7 +12,7 @@ MakeVar ← { program 𝕊 name: Get ⇐ !∘"Runtime: Variable referenced before definition" SetU ⇐ !∘"↩: Variable modified before definition" SetN ⇐ { - Get ↩ {𝕤⋄v} + Get ↩ {𝕊:v} (SetU ↩ {v↩𝕩}) 𝕩 } SetQ ⇐ 0∘SetN @@ -33,9 +33,12 @@ ref ← { # Array destructuring ⟨a,b,c⟩← Array ⇐ {𝕊 arr: Get ⇐ {𝕩.Get@}¨ arr˙ + # Common code for all setter functions + # 𝕨S𝕩 sets reference 𝕨 to 𝕩, and e indicates error handling _set_ ← {S _𝕣_ e: - Err ← {(e∾": "∾𝕩)!e≡@ ⋄ ⟨1⟩} - c ← (e≡@) ⊑ {𝔽}‿{𝔽⎊1} # GetF or Get in F can error + Err ← {(e∾": "∾𝕩)!e≡@ ⋄ ⟨1⟩} # e≡@ indicates SetQ, which can't error + c ← (e≡@) ⊑ {𝔽}‿{𝔽⎊1} # GetF or Get in F can error + # Get field for reference 𝕨 from namespace, if possible F ← {⟨G⇐GetF⟩𝕊𝕩:(G𝕩).Get@ ; !Err"Cannot extract non-name from namespace"} { 0=•Type𝕩 ? arr ≡○≢◶⟨Err∘"Target and value shapes don't match", S¨⟩ 𝕩 ; @@ -47,6 +50,8 @@ ref ← { SetU ⇐ {𝕨.SetU𝕩}_set_"↩" SetQ ⇐ ∨´ {𝕨.SetQ𝕩}_set_@ } + # Alias, like ⇐vals in ⟨a‿b⇐vals⟩← + # It behaves like ⟨a‿b⟩← except when destructuring a namespace (GetF) Alias ⇐ {env‿name 𝕊 r: SetN‿SetU‿SetQ ⇐ r GetF ⇐ {env.program 𝕩.Field name} @@ -83,7 +88,8 @@ MakeEnv ← { 𝕊⟨ # The input is taken from the bytecode stream. VO ← { d←𝕏@, s←𝕏@, s⊑·{𝕩.vars}{𝕩.parent}⍟d } -Namespace ← {𝕩.MakeNS@} # Namespace from environment +# Namespace from environment +Namespace ← {𝕩.MakeNS@} # Read field 𝕨 from program 𝕩, where 𝕨 is the environment and index GetField ← { e‿i 𝕊 𝕩: "Key lookup in non-namespace" ! 6=•Type𝕩 @@ -92,19 +98,24 @@ GetField ← { e‿i 𝕊 𝕩: # Constants nothing ← {⇐} # Used when 𝕨 is · -skipMark ← {⇐} +skipMark ← {⇐} # Indicates body aborted instead of returning +# Execution stack: every body evaluation makes one of these MakeStack ← { s ← 𝕩 # Stack (a list) cont ⇐ 1 # Whether to continue execution rslt ⇐ skipMark # Result: skipMark to abort current body Push ⇐ {s∾↩<𝕩} # Push a value Pop ⇐ {t←-𝕩 ⋄ (s↓˜↩t) ⊢ ⌽t↑s} # Pop 𝕩 values; return as list - Peek ⇐ {𝕤⋄¯1⊑s} # Return but don't pop top value + Peek ⇐ {𝕊:¯1⊑s} # Return but don't pop top value Ret ⇐ {rslt↩𝕩 ⋄ cont↩0 ⋄ "Internal compiler error: Wrong stack size"!𝕨≥≠s} - Skip ⇐ {𝕤⋄ cont↩0} + Skip ⇐ {𝕊: cont↩0} # Exit with no return value } +# All the opcodes +# Each one is a function that takes the next-opcode function so it can +# read values from the bytecode stream. It returns a function to be +# called on the stack s and environment e at evaluation time. ops ← ((!∘"Unknown opcode")˙⊣´⊢)¨ ⊔˝ ⍉> ⟨ # Constants and drop 0‿{i←𝕏@ ⋄ {s𝕊e: s.Push i⊑e.program.consts } } @@ -147,36 +158,41 @@ ops ← ((!∘"Unknown opcode")˙⊣´⊢)¨ ⊔˝ ⍉> ⟨ 66‿{i←𝕏@ ⋄ {s𝕊e: s.Push e‿i ref.Alias ⊑s.Pop 1 } } ⟩ -RunBC ← { bc‿pos‿env: - Next ← {𝕤⋄ (pos+↩1) ⊢ pos⊑bc } +# Evaluate a body +RunBC ← { bc‿pos‿env: # bytecode, starting position, environment + Next ← {𝕊: (pos+↩1) ⊢ pos⊑bc } stack ← MakeStack ⟨⟩ Step ← {𝕊: op ← (Next@) ⊑ ops op ↩ Op next stack Op env - stack.cont + stack.cont # Changes to 0 on return or abort } _while_ ← {𝔽⍟𝔾∘𝔽_𝕣_𝔾∘𝔽⍟𝔾𝕩} Step _while_ ⊢ 1 stack.rslt } +# Evaluate a program, given the compiler output { VM bc‿consts‿blockInfo‿bodyInfo‿loc‿token: bodies ← {start‿vars‿names‿export: + # Called when the body is evaluated {parent 𝕊 args: env ← MakeEnv parent‿vars‿names‿export - (⊢ {𝕩.SetN 𝕨}¨ ≠↑env.vars˙) args + (⊢ {𝕩.SetN 𝕨}¨ ≠↑env.vars˙) args # Initialize arguments RunBC bc‿start‿env } }¨ bodyInfo blocks ← {type‿imm‿body: + # Handle operands inner ← imm ⊑ type ⊑ ⟨ 2⥊⟨{𝕊n: N ⟨⟩}⟩ {𝕊n: {d←N 𝕣‿𝕗 ⋄𝕨D𝕩}}‿{𝕊n: {N 𝕣‿𝕗 }} {𝕊n: {d←N 𝕣‿𝕗‿𝕘⋄𝕨D𝕩}}‿{𝕊n: {N 𝕣‿𝕗‿𝕘}} ⟩ + # Handle arguments outer ← imm ⊑ ⟨ { m‿d: {𝕊v: {M 𝕤‿𝕩‿nothing∾v;D 𝕤‿𝕩‿𝕨∾v}} ; @@ -185,6 +201,7 @@ RunBC ← { bc‿pos‿env: ⊑ ⟩ + # Assemble bodies nmc ← "No matching case" Then ← {first 𝕊 next: {skipMark≢r←𝕨First𝕩 ? r ; 𝕨Next𝕩}} run ← { |
