Skip to content

Commit

Permalink
Completed the SOM bytecode interpreter
Browse files Browse the repository at this point in the history
  • Loading branch information
Hirevo committed Aug 5, 2020
1 parent bf7a0ff commit 697375d
Show file tree
Hide file tree
Showing 64 changed files with 5,243 additions and 153 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/bench.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ jobs:
rebench:
name: Run and report benchmarks
runs-on: ubuntu-latest
strategy:
matrix:
interpreter:
- som-interpreter-ast
- som-interpreter-bc
steps:
- name: Checkout master branch
uses: actions/checkout@v2
Expand All @@ -24,7 +29,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: build
args: --release -p som-interpreter
args: --release -p som-interpreter-ast -p som-interpreter-bc
- name: Install ReBench
run: |
pip install setuptools
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ jobs:
run_test_suite:
name: Run SOM Test Suite
runs-on: ubuntu-latest
strategy:
matrix:
interpreter:
- som-interpreter-ast
- som-interpreter-bc
steps:
- name: Checkout master branch
uses: actions/checkout@v2
Expand All @@ -24,10 +29,10 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: build
args: --release -p som-interpreter
args: --release -p ${{ matrix.interpreter }}
- name: Run test suite
run: |
./target/release/som-interpreter -c core-lib/Smalltalk core-lib/TestSuite -- TestHarness
./target/release/${{ matrix.interpreter }} -c core-lib/Smalltalk core-lib/TestSuite -- TestHarness
run_own_tests:
name: Run own tests
Expand Down
18 changes: 12 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[workspace]
members = [
"som-core",
"som-compiler",
"som-interpreter",
"som-interpreter-bc",
"som-interpreter-ast",
"som-lexer",
"som-parser-core",
"som-parser-symbols",
Expand Down
10 changes: 7 additions & 3 deletions rebench.conf
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,12 @@ benchmark_suites:
- Mandelbrot: {extra_args: 30}

executors:
som-rs:
som-rs-ast:
path: .
executable: ./target/release/som-interpreter-ast
som-rs-bc:
path: .
executable: ./target/release/som-interpreter
executable: ./target/release/som-interpreter-bc

# define the benchmarks to be executed for a re-executable benchmark run
experiments:
Expand All @@ -67,4 +70,5 @@ experiments:
- micro
- macro
executions:
- som-rs
- som-rs-ast
- som-rs-bc
18 changes: 0 additions & 18 deletions som-compiler/Cargo.toml

This file was deleted.

3 changes: 0 additions & 3 deletions som-compiler/src/lib.rs

This file was deleted.

164 changes: 67 additions & 97 deletions som-core/src/bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,23 @@ use std::fmt;

#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[rustfmt::skip]
pub enum Bytecode {
Halt = 0,
Dup = 1,
PushLocal = 2,
PushArgument = 3,
PushField = 4,
PushBlock = 5,
PushConstant = 6,
PushGlobal = 7,
Pop = 8,
PopLocal = 9,
PopArgument = 10,
PopField = 11,
Send = 12,
SuperSend = 13,
ReturnLocal = 14,
ReturnNonLocal = 15,
Halt,
Dup,
PushLocal(u8, u8),
PushArgument(u8, u8),
PushField(u8),
PushBlock(u8),
PushConstant(u8),
PushGlobal(u8),
Pop,
PopLocal(u8, u8),
PopArgument(u8, u8),
PopField(u8),
Send(u8),
SuperSend(u8),
ReturnLocal,
ReturnNonLocal,
}

impl Bytecode {
Expand All @@ -28,22 +27,22 @@ impl Bytecode {
pub fn name(self) -> &'static str {
// NAMES[self as usize]
match self {
Self::Halt => "HALT",
Self::Dup => "DUP",
Self::PushLocal => "PUSH_LOCAL",
Self::PushArgument => "PUSH_ARGUMENT",
Self::PushField => "PUSH_FIELD",
Self::PushBlock => "PUSH_BLOCK",
Self::PushConstant => "PUSH_CONSTANT",
Self::PushGlobal => "PUSH_GLOBAL",
Self::Pop => "POP",
Self::PopLocal => "POP_LOCAL",
Self::PopArgument => "POP_ARGUMENT",
Self::PopField => "POP_FIELD",
Self::Send => "SEND",
Self::SuperSend => "SUPER_SEND",
Self::ReturnLocal => "RETURN_LOCAL",
Self::ReturnNonLocal => "RETURN_NON_LOCAL",
Self::Halt => "HALT",
Self::Dup => "DUP",
Self::PushLocal(_, _) => "PUSH_LOCAL",
Self::PushArgument(_, _) => "PUSH_ARGUMENT",
Self::PushField(_) => "PUSH_FIELD",
Self::PushBlock(_) => "PUSH_BLOCK",
Self::PushConstant(_) => "PUSH_CONSTANT",
Self::PushGlobal(_) => "PUSH_GLOBAL",
Self::Pop => "POP",
Self::PopLocal(_, _) => "POP_LOCAL",
Self::PopArgument(_, _) => "POP_ARGUMENT",
Self::PopField(_) => "POP_FIELD",
Self::Send(_) => "SEND",
Self::SuperSend(_) => "SUPER_SEND",
Self::ReturnLocal => "RETURN_LOCAL",
Self::ReturnNonLocal => "RETURN_NON_LOCAL",
}
}

Expand All @@ -52,69 +51,22 @@ impl Bytecode {
pub fn padded_name(self) -> &'static str {
// PADDED_NAMES[self as usize]
match self {
Self::Halt => "HALT ",
Self::Dup => "DUP ",
Self::PushLocal => "PUSH_LOCAL ",
Self::PushArgument => "PUSH_ARGUMENT ",
Self::PushField => "PUSH_FIELD ",
Self::PushBlock => "PUSH_BLOCK ",
Self::PushConstant => "PUSH_CONSTANT ",
Self::PushGlobal => "PUSH_GLOBAL ",
Self::Pop => "POP ",
Self::PopLocal => "POP_LOCAL ",
Self::PopArgument => "POP_ARGUMENT ",
Self::PopField => "POP_FIELD ",
Self::Send => "SEND ",
Self::SuperSend => "SUPER_SEND ",
Self::ReturnLocal => "RETURN_LOCAL ",
Self::ReturnNonLocal => "RETURN_NON_LOCAL",
}
}

/// Get the number of bytes to read to process the instruction.
#[rustfmt::skip]
pub fn bytecode_len(self) -> usize {
match self {
Self::Halt => 1,
Self::Dup => 1,
Self::PushLocal => 3,
Self::PushArgument => 3,
Self::PushField => 2,
Self::PushBlock => 2,
Self::PushConstant => 2,
Self::PushGlobal => 2,
Self::Pop => 1,
Self::PopLocal => 3,
Self::PopArgument => 3,
Self::PopField => 2,
Self::Send => 2,
Self::SuperSend => 2,
Self::ReturnLocal => 1,
Self::ReturnNonLocal => 1,
}
}

/// Attempt to convert a raw byte to an instruction.
#[rustfmt::skip]
pub fn from_byte(byte: u8) -> Option<Self> {
match byte {
0 => Some(Self::Halt),
1 => Some(Self::Dup),
2 => Some(Self::PushLocal),
3 => Some(Self::PushArgument),
4 => Some(Self::PushField),
5 => Some(Self::PushBlock),
6 => Some(Self::PushConstant),
7 => Some(Self::PushGlobal),
8 => Some(Self::Pop),
9 => Some(Self::PopLocal),
10 => Some(Self::PopArgument),
11 => Some(Self::PopField),
12 => Some(Self::Send),
13 => Some(Self::SuperSend),
14 => Some(Self::ReturnLocal),
15 => Some(Self::ReturnNonLocal),
_ => None,
Self::Halt => "HALT ",
Self::Dup => "DUP ",
Self::PushLocal(_, _) => "PUSH_LOCAL ",
Self::PushArgument(_, _) => "PUSH_ARGUMENT ",
Self::PushField(_) => "PUSH_FIELD ",
Self::PushBlock(_) => "PUSH_BLOCK ",
Self::PushConstant(_) => "PUSH_CONSTANT ",
Self::PushGlobal(_) => "PUSH_GLOBAL ",
Self::Pop => "POP ",
Self::PopLocal(_, _) => "POP_LOCAL ",
Self::PopArgument(_, _) => "POP_ARGUMENT ",
Self::PopField(_) => "POP_FIELD ",
Self::Send(_) => "SEND ",
Self::SuperSend(_) => "SUPER_SEND ",
Self::ReturnLocal => "RETURN_LOCAL ",
Self::ReturnNonLocal => "RETURN_NON_LOCAL",
}
}
}
Expand Down Expand Up @@ -158,7 +110,25 @@ pub static PADDED_NAMES: [&str; 16] = [
];

impl fmt::Display for Bytecode {
#[rustfmt::skip]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name())
match self {
Self::Halt => write!(f, "HALT"),
Self::Dup => write!(f, "DUP"),
Self::PushLocal(up_idx, idx) => write!(f, "PUSH_LOCAL {}, {}", up_idx, idx),
Self::PushArgument(up_idx, idx) => write!(f, "PUSH_ARGUMENT {}, {}", up_idx, idx),
Self::PushField(idx) => write!(f, "PUSH_FIELD {}", idx),
Self::PushBlock(idx) => write!(f, "PUSH_BLOCK {}", idx),
Self::PushConstant(idx) => write!(f, "PUSH_CONSTANT {}", idx),
Self::PushGlobal(idx) => write!(f, "PUSH_GLOBAL {}", idx),
Self::Pop => write!(f, "POP"),
Self::PopLocal(up_idx, idx) => write!(f, "POP_LOCAL {}, {}", up_idx, idx),
Self::PopArgument(up_idx, idx) => write!(f, "POP_ARGUMENT {}, {}", up_idx, idx),
Self::PopField(idx) => write!(f, "POP_FIELD {}", idx),
Self::Send(idx) => write!(f, "SEND {}", idx),
Self::SuperSend(idx) => write!(f, "SUPER_SEND {}", idx),
Self::ReturnLocal => write!(f, "RETURN_LOCAL", ),
Self::ReturnNonLocal => write!(f, "RETURN_NON_LOCAL", ),
}
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
[package]
name = "som-interpreter"
name = "som-interpreter-ast"
version = "0.1.0"
description = "An interpreter for the Simple Object Machine"
authors = ["Nicolas Polomack <[email protected]>"]
edition = "2018"
publish = false
license = "MIT OR Apache-2.0"

[lib]
path = "src/lib.rs"

[[bin]]
name = "som-interpreter"
path = "src/main.rs"

[dependencies]
# internal
som-core = { path = "../som-core", version = "0.1.0" }
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ use structopt::StructOpt;

mod shell;

use som_interpreter::invokable::Return;
use som_interpreter::universe::Universe;
use som_interpreter::value::Value;
use som_interpreter_ast::invokable::Return;
use som_interpreter_ast::universe::Universe;
use som_interpreter_ast::value::Value;

#[derive(Debug, Clone, PartialEq, StructOpt)]
#[structopt(about, author)]
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ use anyhow::Error;
use som_lexer::{Lexer, Token};
use som_parser::lang;

use som_interpreter::evaluate::Evaluate;
use som_interpreter::frame::FrameKind;
use som_interpreter::invokable::Return;
use som_interpreter::universe::Universe;
use som_interpreter::value::Value;
use som_interpreter_ast::evaluate::Evaluate;
use som_interpreter_ast::frame::FrameKind;
use som_interpreter_ast::invokable::Return;
use som_interpreter_ast::universe::Universe;
use som_interpreter_ast::value::Value;

/// Launches an interactive Read-Eval-Print-Loop within the given universe.
pub fn interactive(universe: &mut Universe, verbose: bool) -> Result<(), Error> {
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::path::PathBuf;

use som_interpreter::evaluate::Evaluate;
use som_interpreter::frame::FrameKind;
use som_interpreter::invokable::Return;
use som_interpreter::universe::Universe;
use som_interpreter::value::Value;
use som_interpreter_ast::evaluate::Evaluate;
use som_interpreter_ast::frame::FrameKind;
use som_interpreter_ast::invokable::Return;
use som_interpreter_ast::universe::Universe;
use som_interpreter_ast::value::Value;
use som_lexer::{Lexer, Token};

use som_parser::lang;
Expand Down
Loading

0 comments on commit 697375d

Please sign in to comment.