Amogulator/Suslang/VM.cs
2023-03-14 12:53:56 +01:00

76 lines
3.1 KiB
C#

using System.Collections.Generic;
namespace Amogulator.Suslang;
public interface Value {
string valueString();
}
public class IntValue : Value {
public int value;
public string valueString() => $"{this.value}";
}
public class FloatValue : Value {
public double value;
public string valueString() => $"{this.value}";
}
public class VM {
private int pc = 0;
private List<Operation> program;
public Stack<Value> stack = new();
public VM(List<Operation> program) {
this.program = program;
}
public void evaluate() {
while (this.pc < this.program.Count) {
switch (this.program[this.pc]) {
case PushIntOperation op:
this.stack.Push(new IntValue() { value = op.value });
break;
case PushFloatOperation op:
this.stack.Push(new FloatValue() { value = op.value });
break;
case AddIntOperation:
this.stack.Push(new IntValue() { value = ((IntValue) this.stack.Pop()).value + ((IntValue) this.stack.Pop()).value });
break;
case SubtractIntOperation:
this.stack.Push(new IntValue() { value = ((IntValue) this.stack.Pop()).value - ((IntValue) this.stack.Pop()).value });
break;
case MultiplyIntOperation:
this.stack.Push(new IntValue() { value = ((IntValue) this.stack.Pop()).value * ((IntValue) this.stack.Pop()).value });
break;
case DivideIntOperation:
this.stack.Push(new IntValue() { value = ((IntValue) this.stack.Pop()).value / ((IntValue) this.stack.Pop()).value });
break;
case ModuloIntOperation:
this.stack.Push(new IntValue() { value = ((IntValue) this.stack.Pop()).value % ((IntValue) this.stack.Pop()).value });
break;
case AddFloatOperation:
this.stack.Push(new FloatValue() { value = ((FloatValue) this.stack.Pop()).value + ((FloatValue) this.stack.Pop()).value });
break;
case SubtractFloatOperation:
this.stack.Push(new FloatValue() { value = ((FloatValue) this.stack.Pop()).value - ((FloatValue) this.stack.Pop()).value });
break;
case MultiplyFloatOperation:
this.stack.Push(new FloatValue() { value = ((FloatValue) this.stack.Pop()).value * ((FloatValue) this.stack.Pop()).value });
break;
case DivideFloatOperation:
this.stack.Push(new FloatValue() { value = ((FloatValue) this.stack.Pop()).value / ((FloatValue) this.stack.Pop()).value });
break;
case ModuloFloatOperation:
this.stack.Push(new FloatValue() { value = ((FloatValue) this.stack.Pop()).value % ((FloatValue) this.stack.Pop()).value });
break;
default:
break;
}
this.pc += 1;
}
}
}