-
Notifications
You must be signed in to change notification settings - Fork 3
Add Maroon JSON DSL and Bytecode Executor #44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@dkorolev please re-review it. |
| struct MaroonVM { | ||
| program: Program, | ||
| stack: Vec<StackEntry>, | ||
| local_vars: HashMap<String, u64>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
heap?
| } | ||
|
|
||
| impl MaroonVM { | ||
| fn new(program: Program) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you need the initial state, and perhaps its arguments? So that the invalid states are not representable?
|
|
||
| fn evaluate_expression(&self, expr: &Expression) -> u64 { | ||
| match expr { | ||
| Expression::Var { var } => *self.local_vars.get(var).unwrap_or(&0), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just .unwrap(), this _or(&0) doesn't look safe to me.
| } | ||
|
|
||
| fn evaluate_stack_value(&self, value: &StackValue) -> u64 { | ||
| match value { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There got to be some visitor pattern for this in Rust, natively — no?
| fn interpolate_text(&self, text: &str) -> String { | ||
| let mut result = text.to_string(); | ||
| for (var, value) in &self.local_vars { | ||
| result = result.replace(&format!("{{{}}}", var), &value.to_string()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Me confused. Needs a comment or pls make it more self-descriptive, it's write-only as of now.
| .context("Entry point function not found")?; | ||
|
|
||
| // Initialize stack with entry state | ||
| self.local_vars.insert("n".to_string(), initial_arg); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also making too many assumptions — just a u64, called "n". Need to find a way to do it cleaner, although the code most definitely LGTM.
|
|
||
|
|
||
| // Update local variables based on state | ||
| if current_state_name.contains("PostRecursiveCall") && local_values.len() >= 2 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, what?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
definitely a bug
| let mut continue_to_next_iteration = false; | ||
| for op in &state_def.operations { | ||
| match &op.op_type[..] { | ||
| "push_stack" => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's avoid this. Parse the JSON into a strongly typed object first pls.
| let mut pushed_stack = false; | ||
| for exec_op in ops_to_execute { | ||
| match &exec_op.op_type[..] { | ||
| "return" => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This inner part looks redundant to me.
dkorolev
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
For this to be self-contained, perhaps present it as a command-line tool, which gets three inputs: path to the .json with the code, path to the .json with the "call spec", and the name of the function to execute?
Overall I'd say it's good to merge! And let's stop abusing the rust-experiments repo, it's about time =)
|
Thanks for your time and looking into it!
Sounds right to me.
Noted with thanks. |
Summary
This PR introduces
step13_maroon_json, a Rust implementation of a stack-based virtual machine that executes JSON bytecode. The VM provides a portable, language-agnostic bytecode format for executing computational tasks with state management, timing control, and output capabilities.What's New
mul,sub) and comparisons (le)Technical Details
The VM implements a stack-based execution model with three core data types:
Stateentries for control flowRetrnentries for function return addressesValueentries for computational dataSupported operations:
push_stack- Push entries onto the execution stackwrite- Output text with variable interpolationsleep- Async delay with expression-based durationconditional- Branching based on expression evaluationreturn- Return computed values to callerdone- Terminate executionExample
Architecture Benefits
Files Added
step13_maroon_json/code/src/main.rs- VM implementationstep13_maroon_json/code/Cargo.toml- Rust dependenciesstep13_maroon_json/README.md- Documentationstep13_maroon_json/run.sh- Execution scriptTesting
This executes the factorial example from factorial_bytecode.json and demonstrates the VM's capabilities.