RosettaCodeData/Task/Execute-Brain-/Objeck/execute-brain-.objeck
2023-07-01 13:44:08 -04:00

70 lines
1.7 KiB
Text

class Brainfu_k {
@program : String; @mem : Int[];
@ip : Int; @dp : Int;
New(program : String, size : Int) {
@program := program;
@mem := Int → New[size];
}
function : Main(args : String[]) ~ Nil {
if(args → Size() = 2) {
Brainfu_k → New(args[0], args[1] → ToInt()) → Execute();
};
}
method : Execute() ~ Nil {
while(@ip < @program → Size()) {
instr := @program → Get(@ip);
select(instr) {
label '>': { @dp += 1; }
label '<': { @dp -= 1; }
label '+': { @mem[@dp] := @mem[@dp] + 1; }
label '-': { @mem[@dp] := @mem[@dp] - 1; }
label '.': { value := @mem[@dp] → As(Char); value → Print(); }
label ',': { @mem[@dp] := Read(); }
label '[': { JumpForward(); }
label ']': { JumpBack(); }
};
@ip += 1;
};
}
method : JumpForward() ~ Nil {
depth := 1;
if(@mem[@dp] = 0) {
while(@ip < @program → Size()) {
instr := @program → Get(@ip);
if(instr = ']') {
depth -= 1; if(depth = 0) { return; };
}
else if(instr = '[') { depth += 1; };
@ip += 1;
};
"*** Unbalanced jump ***" → ErrorLine();
Runtime → Exit(1);
};
}
method : JumpBack() ~ Nil {
depth := 1;
if(@mem[@dp] <> 0) {
while(@ip > 0) {
@ip -= 1;
instr := @program → Get(@ip);
if(instr = '[') {
depth -= 1; if(depth = 0) { return; };
}
else if(instr = ']') { depth += 1; };
};
"*** Unbalanced jump ***" → ErrorLine();
Runtime → Exit(1);
};
}
method : Read() ~ Int {
in := IO.Console → ReadString();
if(in → Size() > 0) { return in → ToInt(); };
return 0;
}
}