diff options
Diffstat (limited to 'pkg/lang/vm/code')
| -rw-r--r-- | pkg/lang/vm/code/code.go | 59 | ||||
| -rw-r--r-- | pkg/lang/vm/code/op.go | 34 |
2 files changed, 93 insertions, 0 deletions
diff --git a/pkg/lang/vm/code/code.go b/pkg/lang/vm/code/code.go new file mode 100644 index 0000000..ab06d27 --- /dev/null +++ b/pkg/lang/vm/code/code.go @@ -0,0 +1,59 @@ +package code + +import ( + "bytes" + "encoding/binary" + "math" + "strings" +) + +type Code struct { + code []byte +} + +func (c *Code) Len() int { + return len(c.code) +} + +func (c *Code) GetOp(at int) (Op, int) { + return Op(c.code[at]), 1 +} + +func (c *Code) GetUint(at int) (uint64, int) { + advance := 8 + x := binary.LittleEndian.Uint64(c.code[at : at+advance]) + return x, advance +} + +func (c *Code) GetInt(at int) (int64, int) { + x, advance := c.GetUint(at) + return int64(x), advance +} + +func (c *Code) GetFloat(at int) (float64, int) { + x, advance := c.GetUint(at) + return math.Float64frombits(x), advance +} + +func (c *Code) GetString(at int) (string, int) { + advance := 0 + reader := bytes.NewReader(c.code[at:]) + builder := strings.Builder{} + + for { + r, size, err := reader.ReadRune() + advance += size + + if err != nil { + break + } + + if r == 0 { + break + } + + builder.WriteRune(r) + } + + return builder.String(), advance +} diff --git a/pkg/lang/vm/code/op.go b/pkg/lang/vm/code/op.go new file mode 100644 index 0000000..ae37603 --- /dev/null +++ b/pkg/lang/vm/code/op.go @@ -0,0 +1,34 @@ +package code + +type Op uint8 + +const ( + OpNop Op = iota + OpHalt + + OpPushInt + OpPushFloat + OpPushString + OpPushTrue + OpPushFalse + OpPushNull + OpPushArray + OpPushFunction + OpPushObject + + OpGetGlobal + OpGetLocal + OpGetMember + OpGetArg + OpGetEnv + + OpAdd + OpSub + OpIndex + OpCall + + OpJmp + OpJez + + OpRet +) |
