mirror of
https://github.com/allaunthefox/SilverSight.git
synced 2026-08-20 13:57:29 +00:00
fix(go): remove duplicate AVMIsa/avm.go, fix recover scope
This commit is contained in:
parent
a6db85ab5e
commit
3e50e292ba
1 changed files with 0 additions and 138 deletions
138
go/AVMIsa/avm.go
138
go/AVMIsa/avm.go
|
|
@ -1,138 +0,0 @@
|
||||||
// AVM ISA v1 — Go Port (Strict Functional Execution)
|
|
||||||
package avm
|
|
||||||
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
const Q16Scale = 65536
|
|
||||||
|
|
||||||
func q16Mul(a, b int32) int32 {
|
|
||||||
return int32((int64(a) * int64(b)) / Q16Scale)
|
|
||||||
}
|
|
||||||
func q16Div(a, b int32) (int32, error) {
|
|
||||||
if b == 0 { return 0, errors.New("div by zero") }
|
|
||||||
return int32((int64(a) * Q16Scale) / b), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Value ─────────────────────────────────────────
|
|
||||||
type ValType int
|
|
||||||
const (
|
|
||||||
ValQ0 ValType = iota
|
|
||||||
ValQ16
|
|
||||||
ValBool
|
|
||||||
)
|
|
||||||
type AvmVal struct { Ty ValType; Raw int32 }
|
|
||||||
|
|
||||||
func Q16(x int32) AvmVal { return AvmVal{ValQ16, x} }
|
|
||||||
func Bool(x bool) AvmVal {
|
|
||||||
if x { return AvmVal{ValBool, 1} }
|
|
||||||
return AvmVal{ValBool, 0}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Primitives ─────────────────────────────────────
|
|
||||||
type Prim int
|
|
||||||
const (
|
|
||||||
AddQ16 Prim = iota; SubQ16; MulQ16; DivQ16; LtQ16; EqQ16; And; Or; Not
|
|
||||||
)
|
|
||||||
|
|
||||||
func execPrim(p Prim, a, b AvmVal) (AvmVal, error) {
|
|
||||||
switch p {
|
|
||||||
case AddQ16: return Q16(a.Raw + b.Raw), nil
|
|
||||||
case SubQ16: return Q16(a.Raw - b.Raw), nil
|
|
||||||
case MulQ16: return Q16(q16Mul(a.Raw, b.Raw)), nil
|
|
||||||
case DivQ16:
|
|
||||||
r, e := q16Div(a.Raw, b.Raw)
|
|
||||||
return Q16(r), e
|
|
||||||
case LtQ16: return Bool(a.Raw < b.Raw), nil
|
|
||||||
case EqQ16: return Bool(a.Raw == b.Raw), nil
|
|
||||||
case And: return Bool(a.Raw != 0 && b.Raw != 0), nil
|
|
||||||
case Or: return Bool(a.Raw != 0 || b.Raw != 0), nil
|
|
||||||
case Not: return Bool(a.Raw == 0), nil
|
|
||||||
}
|
|
||||||
return AvmVal{}, errors.New("unknown prim")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Instruction ────────────────────────────────────
|
|
||||||
type InstrOp int
|
|
||||||
const (
|
|
||||||
PushQ16 InstrOp = iota; PushBool; Pop; Dup; Swap; Load; Store; Jump; JumpIf; PrimOp; Halt
|
|
||||||
)
|
|
||||||
type Instr struct { Op InstrOp; Arg int32; Arg2 bool }
|
|
||||||
|
|
||||||
func Push(x int32) Instr { return Instr{PushQ16, x, false} }
|
|
||||||
func PushB(x bool) Instr { return Instr{PushBool, boolTo32(x), true} }
|
|
||||||
func Pop() Instr { return Instr{Pop, 0, false} }
|
|
||||||
func Dup() Instr { return Instr{Dup, 0, false} }
|
|
||||||
func Swap() Instr { return Instr{Swap, 0, false} }
|
|
||||||
func Load(i int) Instr { return Instr{Load, int32(i), false} }
|
|
||||||
func Store(i int) Instr { return Instr{Store, int32(i), false} }
|
|
||||||
func Jump(t int) Instr { return Instr{Jump, int32(t), false} }
|
|
||||||
func JumpIf(t int) Instr { return Instr{JumpIf, int32(t), false} }
|
|
||||||
func PrimOp(p Prim) Instr{ return Instr{PrimOp, int32(p), false} }
|
|
||||||
func Halt() Instr { return Instr{Halt, 0, false} }
|
|
||||||
|
|
||||||
func boolTo32(x bool) int32 { if x { return 1 }; return 0 }
|
|
||||||
|
|
||||||
// ── State ──────────────────────────────────────────
|
|
||||||
type State struct {
|
|
||||||
Pc int
|
|
||||||
Stack []AvmVal
|
|
||||||
Locals []*AvmVal
|
|
||||||
Halted bool
|
|
||||||
}
|
|
||||||
func NewState(n int) State {
|
|
||||||
return State{0, []AvmVal{}, make([]*AvmVal, n), false}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Step ───────────────────────────────────────────
|
|
||||||
func Step(s State, prog []Instr) (State, error) {
|
|
||||||
if s.Halted { return s, errors.New("halted") }
|
|
||||||
if s.Pc < 0 || s.Pc >= len(prog) {
|
|
||||||
s.Halted = true; return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
instr := prog[s.Pc]
|
|
||||||
ns := State{s.Pc + 1, append([]AvmVal{}, s.Stack...),
|
|
||||||
append([]*AvmVal{}, s.Locals...), false}
|
|
||||||
st := &ns.Stack
|
|
||||||
|
|
||||||
switch instr.Op {
|
|
||||||
case PushQ16: *st = append(*st, Q16(instr.Arg))
|
|
||||||
case PushBool: *st = append(*st, Bool(instr.Arg != 0))
|
|
||||||
case Pop: *st = (*st)[:len(*st)-1]
|
|
||||||
case Dup: *st = append(*st, (*st)[len(*st)-1])
|
|
||||||
case Swap:
|
|
||||||
(*st)[len(*st)-2], (*st)[len(*st)-1] = (*st)[len(*st)-1], (*st)[len(*st)-2]
|
|
||||||
case Load:
|
|
||||||
if ns.Locals[instr.Arg] == nil { return s, errors.New("missing local") }
|
|
||||||
*st = append(*st, *ns.Locals[instr.Arg])
|
|
||||||
case Store:
|
|
||||||
ns.Locals[instr.Arg] = &(*st)[len(*st)-1]
|
|
||||||
*st = (*st)[:len(*st)-1]
|
|
||||||
case Jump: ns.Pc = int(instr.Arg)
|
|
||||||
case JumpIf:
|
|
||||||
v := (*st)[len(*st)-1]; *st = (*st)[:len(*st)-1]
|
|
||||||
if v.Raw != 0 { ns.Pc = int(instr.Arg) }
|
|
||||||
case PrimOp: {
|
|
||||||
p := Prim(instr.Arg)
|
|
||||||
arity := 2; if p == Not { arity = 1 }
|
|
||||||
var b AvmVal
|
|
||||||
if arity == 2 { b = (*st)[len(*st)-1]; *st = (*st)[:len(*st)-1] }
|
|
||||||
a := (*st)[len(*st)-1]; *st = (*st)[:len(*st)-1]
|
|
||||||
r, e := execPrim(p, a, b)
|
|
||||||
if e != nil { return s, e }
|
|
||||||
*st = append(*st, r)
|
|
||||||
}
|
|
||||||
case Halt: ns.Halted = true
|
|
||||||
}
|
|
||||||
return ns, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Run(init State, prog []Instr, fuel int) (State, error) {
|
|
||||||
s := init
|
|
||||||
for i := 0; i < fuel && !s.Halted; i++ {
|
|
||||||
var e error
|
|
||||||
s, e = Step(s, prog)
|
|
||||||
if e != nil { return s, e }
|
|
||||||
}
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
Loading…
Add table
Reference in a new issue