Marahin/yaaibig

View on GitHub
operators.go

Summary

Maintainability
A
0 mins
Test Coverage
package main
 
import (
"fmt"
"os"
"reflect"
"sort"
)
 
var OPERATORS = map[string]interface{}{
"MOV": gasm_MOV,
"mov": gasm_MOV,
 
"ADD": gasm_ADD,
"add": gasm_ADD,
 
"MUL": gasm_MUL,
"mul": gasm_MUL,
 
"JNZ": gasm_JNZ,
"jnz": gasm_JNZ,
 
"JMP": gasm_JMP,
"jmp": gasm_JMP,
 
"RET": gasm_RET,
"ret": gasm_RET,
 
"INT": gasm_INT,
"int": gasm_INT,
 
"_MEMDUMP": gasm_MEMDUMP,
"_INSTRUCTION_DUMP": gasm_INSTRUCTION_DUMP,
}
 
func call(operator_name string, params ...interface{}) (result []reflect.Value, err error) {
f := reflect.ValueOf(OPERATORS[operator_name])
if len(params) != f.Type().NumIn() {
fmt.Fprintf(os.Stderr, "error: The number of parameters is not adapted.\n")
os.Exit(1)
}
in := make([]reflect.Value, len(params))
for k, param := range params {
in[k] = reflect.ValueOf(param)
}
result = f.Call(in)
return
}
 
func gasm_MOV(cell rune, value interface{}) {
switch value_type := value.(type) {
case rune:
REGISTER[cell] = REGISTER[value.(rune)]
case int:
REGISTER[cell] = value.(int)
case string:
REGISTER[cell] = value.(string)
default:
fmt.Fprintf(os.Stderr, "error: Unsupported type: %T\n", value_type)
os.Exit(1)
}
}
 
func gasm_INT(value interface{}) {
debugOutput("REGISTER['m']: %v\n", REGISTER['m'])
switch value_type := value.(type) {
case string:
switch value.(string) {
case "21h":
_int_21h()
}
default:
fmt.Fprintf(os.Stderr, "error: Unsupported type: %T\n", value_type)
os.Exit(1)
}
}
 
func gasm_JNZ(value interface{}) {
if currentMemory() != 0 {
switch value_type := value.(type) {
case rune:
REGISTER['i'] = REGISTER[value.(rune)].(int) - 1
case int:
REGISTER['i'] = value.(int) - 1
default:
fmt.Fprintf(os.Stderr, "error: Unsupported type: %T\n", value_type)
os.Exit(1)
}
}
}
 
func gasm_JMP(value interface{}) {
switch value_type := value.(type) {
case rune:
REGISTER['i'] = REGISTER[value.(rune)].(int) - 1
case int:
REGISTER['i'] = value.(int) - 1
default:
fmt.Fprintf(os.Stderr, "error: Unsupported type: %T\n", value_type)
os.Exit(1)
}
}
 
func gasm_ADD(value1, value2 interface{}) {
sum := 0
values := []interface{}{value1, value2}
for _, value := range values {
switch value_type := value.(type) {
case rune:
sum += REGISTER[value.(rune)].(int)
case int:
sum += value.(int)
default:
fmt.Fprintf(os.Stderr, "error: Unsupported type: %T\n", value_type)
os.Exit(1)
}
}
 
REGISTER['m'] = sum
}
 
func gasm_RET(value interface{}) {
switch value_type := value.(type) {
case rune:
os.Exit(REGISTER[value.(rune)].(int))
case int:
os.Exit(value.(int))
default:
fmt.Fprintf(os.Stderr, "error: Unsupported type: %T\n", value_type)
os.Exit(1)
}
}
 
func gasm_MUL(value1, value2 interface{}) {
base := 0
multiplier := 0
 
switch value1_type := value1.(type) {
case rune:
base = REGISTER[value1.(rune)].(int)
case int:
base = value1.(int)
default:
fmt.Fprintf(os.Stderr, "error: Unsupported type: %T\n", value1_type)
os.Exit(1)
}
 
switch value2_type := value2.(type) {
case rune:
multiplier = REGISTER[value2.(rune)].(int)
case int:
multiplier = value2.(int)
default:
fmt.Fprintf(os.Stderr, "error: Unsupported type: %T\n", value2_type)
os.Exit(1)
}
 
REGISTER['m'] = base * multiplier
}
 
func gasm_INSTRUCTION_DUMP() {
fmt.Printf("--- gasm_INSTRUCTION_DUMP: ---\n")
for id, val := range INSTRUCTION_SET {
fmt.Printf("%v: %s\n", id, val)
}
}
 
func gasm_MEMDUMP() {
fmt.Printf("--- gasm_MEMDUMP: ---\n")
var keys []rune
for k := range REGISTER {
keys = append(keys, k)
}
sort.Slice(keys, func(i, j int) bool {
return keys[i] < keys[j]
})
 
for _, k := range keys {
fmt.Printf("REGISTER %v = %v\n", string(k), REGISTER[k])
}
}