M Cargo.lock => Cargo.lock +196 -5
@@ 354,6 354,18 @@ dependencies = [
]
[[package]]
+name = "anes"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
+
+[[package]]
+name = "anstyle"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
+
+[[package]]
name = "approx"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 1370,6 1382,12 @@ dependencies = [
]
[[package]]
+name = "cast"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
+
+[[package]]
name = "cc"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 1398,6 1416,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
[[package]]
+name = "ciborium"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e"
+dependencies = [
+ "ciborium-io",
+ "ciborium-ll",
+ "serde",
+]
+
+[[package]]
+name = "ciborium-io"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757"
+
+[[package]]
+name = "ciborium-ll"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
+dependencies = [
+ "ciborium-io",
+ "half",
+]
+
+[[package]]
+name = "clap"
+version = "4.5.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c937d4061031a6d0c8da4b9a4f98a172fc2976dfb1c19213a9cf7d0d3c837e36"
+dependencies = [
+ "clap_builder",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.5.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85379ba512b21a328adf887e85f7742d12e96eb31f3ef077df4ffc26b506ffed"
+dependencies = [
+ "anstyle",
+ "clap_lex",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
+
+[[package]]
name = "codespan-reporting"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 1582,6 1652,42 @@ dependencies = [
]
[[package]]
+name = "criterion"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f"
+dependencies = [
+ "anes",
+ "cast",
+ "ciborium",
+ "clap",
+ "criterion-plot",
+ "is-terminal",
+ "itertools",
+ "num-traits",
+ "once_cell",
+ "oorandom",
+ "plotters",
+ "rayon",
+ "regex",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "tinytemplate",
+ "walkdir",
+]
+
+[[package]]
+name = "criterion-plot"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
+dependencies = [
+ "cast",
+ "itertools",
+]
+
+[[package]]
name = "crossbeam"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 1638,6 1744,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
[[package]]
+name = "crunchy"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
+
+[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 2221,6 2333,16 @@ dependencies = [
]
[[package]]
+name = "half"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888"
+dependencies = [
+ "cfg-if",
+ "crunchy",
+]
+
+[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 2384,6 2506,15 @@ dependencies = [
]
[[package]]
+name = "itertools"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
+dependencies = [
+ "either",
+]
+
+[[package]]
name = "itoa"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 2447,12 2578,8 @@ dependencies = [
[[package]]
name = "kabel"
version = "0.1.0"
-
-[[package]]
-name = "kabel_test"
-version = "0.1.0"
dependencies = [
- "kabel",
+ "criterion",
"test_each_file",
]
@@ 2973,6 3100,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
+name = "oorandom"
+version = "11.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9"
+
+[[package]]
name = "orbclient"
version = "0.3.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 3119,6 3252,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
+name = "plotters"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3"
+dependencies = [
+ "num-traits",
+ "plotters-backend",
+ "plotters-svg",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "plotters-backend"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7"
+
+[[package]]
+name = "plotters-svg"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705"
+dependencies = [
+ "plotters-backend",
+]
+
+[[package]]
name = "polling"
version = "3.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 3314,6 3475,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
[[package]]
+name = "rayon"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
+dependencies = [
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
+dependencies = [
+ "crossbeam-deque",
+ "crossbeam-utils",
+]
+
+[[package]]
name = "rectangle-pack"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 3969,6 4150,16 @@ dependencies = [
]
[[package]]
+name = "tinytemplate"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
+dependencies = [
+ "serde",
+ "serde_json",
+]
+
+[[package]]
name = "tinyvec"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
M Cargo.toml => Cargo.toml +1 -1
@@ 4,7 4,7 @@ members = [
"starkingdoms-backplane",
"starkingdoms-common",
"savefile_decoder"
-, "starkingdoms-api", "kabel", "kabel_test"]
+, "starkingdoms-api", "kabel"]
resolver = "2"
[profile.dev.package."*"]
M kabel/Cargo.toml => kabel/Cargo.toml +2 -0
@@ 4,6 4,8 @@ version = "0.1.0"
edition = "2021"
[dependencies]
+criterion = "0.5.1"
+test_each_file = "0.3.3"
[features]
timer = []
M kabel/src/codegen.rs => kabel/src/codegen.rs +7 -0
@@ 25,6 25,9 @@ impl Codegen {
Block(stmts) => {
self.visit_block(stmts);
}
+ Expr(expr) => {
+ self.visit_expr_stmt(*expr);
+ }
// REMOVE LATER
Print(ref expr) => {
self.visit_print(&ast, *expr.clone());
@@ 82,6 85,10 @@ impl Codegen {
self.visit(stmt);
}
}
+ pub fn visit_expr_stmt(&mut self, expr: AST) {
+ self.visit(expr);
+ self.vm.chunk.push(OpCode::POP.into());
+ }
// REMOVE LATER
pub fn visit_print(&mut self, ast: &AST, expr: AST) {
self.visit(expr);
M kabel/src/debug.rs => kabel/src/debug.rs +16 -2
@@ 1,4 1,4 @@
-use crate::{lexer::Token, parser::AST, push_output};
+use crate::{lexer::Token, parser::AST, push_output, vm::Value};
pub fn debug_token_array(tokens: Vec<Token>) -> String {
let mut output = "".to_string();
@@ 97,6 97,11 @@ pub fn debug_ast(ast: AST, level: usize) -> String {
output += &debug_ast(ast, level+1);
}
}
+ Expr(expr) => {
+ output += &"| ".repeat(level);
+ output += "Expr\n";
+ output += &debug_ast(*expr, level+1);
+ }
// REMOVE LATER
Print(expr) => {
output += &"| ".repeat(level);
@@ 196,7 201,7 @@ pub fn debug_ast(ast: AST, level: usize) -> String {
output
}
-pub fn debug_bytecode(code: Vec<u8>) -> String {
+pub fn debug_bytecode(code: &Vec<u8>) -> String {
use crate::opcodes::OpCode::*;
let mut ip = 0;
let mut output = "".to_string();
@@ 247,6 252,7 @@ pub fn debug_bytecode(code: Vec<u8>) -> String {
output += &(byte_one | byte_two).to_string();
output += "\n";
}
+ POP => { output += &ip.to_string(); output += " POP\n" }
PRINT => { output += &ip.to_string(); output += " PRINT\n" }
ERR => output += "ERR\n",
}
@@ 254,3 260,11 @@ pub fn debug_bytecode(code: Vec<u8>) -> String {
}
output
}
+pub fn debug_stack(stack: &Vec<Value>) -> String {
+ let mut output = "".to_string();
+ for value in stack.iter().rev() {
+ output += &format!("{:?}", value);
+ output += "\n";
+ }
+ output
+}
M kabel/src/lib.rs => kabel/src/lib.rs +1 -0
@@ 16,6 16,7 @@ pub mod semantic_analysis;
pub mod opcodes;
pub mod codegen;
pub mod vm;
+pub mod test;
pub fn run_lexer(input: String) -> Lexer {
let mut lexer = Lexer::new(input);
R kabel_test/src/main.rs => kabel/src/main.rs +7 -14
@@ 2,23 2,16 @@
use std::{env, fs};
-use kabel::{debug::{debug_ast, debug_bytecode, debug_token_array}, run_codegen, run_lexer, run_parser, run_semantic_analysis};
+use kabel::{debug::{debug_ast, debug_bytecode, debug_stack, debug_token_array}, run_codegen, run_lexer, run_parser, run_semantic_analysis};
fn main() {
- let args: Vec<String> = env::args().collect();
+ /*let args: Vec<String> = env::args().collect();
let program =
- fs::read_to_string(args[1].clone()).unwrap();
+ fs::read_to_string(args[1].clone()).unwrap();*/
- /*let program =
-"if(true) {
- print \"if\";
-} else if(true) {
- print \"elseif\";
-} else {
- print \"else\";
-}
-print \"after\";
-".to_string();*/
+ let program =
+"2+2;
+".to_string();
let mut output = "".to_string();
@@ 61,7 54,7 @@ print \"after\";
let codegen = run_codegen(program, ast);
let mut vm = codegen.vm;
- output += &debug_bytecode(vm.chunk.clone());
+ output += &debug_bytecode(&vm.chunk);
output += "\n";
match vm.run(&mut output) {
Ok(()) => {}
M kabel/src/opcodes.rs => kabel/src/opcodes.rs +3 -0
@@ 26,6 26,7 @@ pub enum OpCode {
JMP,
IF_NE,
+ POP,
PRINT,
ERR,
}
@@ 59,6 60,7 @@ impl From<OpCode> for u8 {
JMP => 0x13,
IF_NE => 0x14,
+ POP => 0xFD,
PRINT => 0xFE,
ERR => 0xFF
}
@@ 93,6 95,7 @@ impl From<u8> for OpCode {
0x13 => JMP,
0x14 => IF_NE,
+ 0xFD => POP,
0xFE => PRINT,
_ => ERR
}
M kabel/src/parser.rs => kabel/src/parser.rs +5 -3
@@ 322,7 322,8 @@ impl Parser {
}
let semicolon = self.read_token()?;
if let TokenType::Semicolon = semicolon.token_type {
- return Ok(expression);
+ return Ok(ast_from_ast_token!(ASTType::Expr(Box::new(expression.clone())),
+ expression, semicolon));
} else {
self.current -= 1;
return Err(unexpected_token!(self, "Expected ; found {}", semicolon));
@@ 1083,8 1084,9 @@ pub enum ASTType {
), // expr1, expr2, expr3, block
Break,
Continue,
- If(Box<AST>, Box<AST>, Box<Option<AST>>), // condition, block, else/else if
- Block(Vec<AST>), // statements
+ If(Box<AST>, Box<AST>, Box<Option<AST>>), // condition, block, else/else if
+ Block(Vec<AST>), // statements
+ Expr(Box<AST>), // expr
// REMOVE LATER
Print(Box<AST>),
M kabel/src/semantic_analysis.rs => kabel/src/semantic_analysis.rs +3 -0
@@ 43,6 43,9 @@ impl Analyzer {
Block(stmts) => {
self.visit_block(stmts);
}
+ Expr(expr) => {
+ self.visit(*expr);
+ }
// REMOVE LATER
Print(expr) => {
self.visit_print(*expr);
R kabel_test/src/lib.rs => kabel/src/test.rs +6 -5
@@ 1,9 1,10 @@
-use kabel::{debug::{debug_ast, debug_token_array}, run_lexer, run_parser, run_semantic_analysis};
use test_each_file::test_each_file;
-test_each_file! { for ["kab", "out"] in "./kabel_test/test/runtime/" => test }
-test_each_file! { for ["kab", "out"] in "./kabel_test/test/lexer/" => test_lexer }
-test_each_file! { for ["kab", "out"] in "./kabel_test/test/syntax/" => test_parser }
+use crate::{debug::{debug_ast, debug_token_array}, run_lexer, run_parser};
+
+test_each_file! { for ["kab", "out"] in "./kabel/test/runtime/" => test }
+test_each_file! { for ["kab", "out"] in "./kabel/test/lexer/" => test_lexer }
+test_each_file! { for ["kab", "out"] in "./kabel/test/syntax/" => test_parser }
fn test_lexer([program, out]: [&str; 2]) {
let mut output = "".to_string();
@@ 55,5 56,5 @@ fn test_parser([program, out]: [&str; 2]) {
assert_eq!(output.trim(), out.trim());
}
fn test([program, out]: [&str; 2]) {
- assert_eq!(kabel::compile(program.to_string()).trim(), out.trim());
+ assert_eq!(crate::compile(program.to_string()).trim(), out.trim());
}
M kabel/src/vm.rs => kabel/src/vm.rs +3 -0
@@ 249,6 249,9 @@ impl VM {
}
}
+ 0xFD => { // POP
+ self.stack.pop().unwrap();
+ }
0xFE => { // PRINT
let value = self.stack.pop().unwrap();
match value {
R kabel_test/test/lexer/arithmetic.kab => kabel/test/lexer/arithmetic.kab +0 -0
R kabel_test/test/lexer/arithmetic.out => kabel/test/lexer/arithmetic.out +0 -0
R kabel_test/test/lexer/declaration.kab => kabel/test/lexer/declaration.kab +0 -0
R kabel_test/test/lexer/declaration.out => kabel/test/lexer/declaration.out +0 -0
R kabel_test/test/lexer/keywords.kab => kabel/test/lexer/keywords.kab +0 -0
R kabel_test/test/lexer/keywords.out => kabel/test/lexer/keywords.out +0 -0
R kabel_test/test/runtime/arithmetic_run.kab => kabel/test/runtime/arithmetic_run.kab +0 -0
R kabel_test/test/runtime/arithmetic_run.out => kabel/test/runtime/arithmetic_run.out +0 -0
R kabel_test/test/runtime/fn_absent_block.kab => kabel/test/runtime/fn_absent_block.kab +0 -0
R kabel_test/test/runtime/fn_absent_block.out => kabel/test/runtime/fn_absent_block.out +0 -0
R kabel_test/test/runtime/if_statement.kab => kabel/test/runtime/if_statement.kab +0 -0
R kabel_test/test/runtime/if_statement.out => kabel/test/runtime/if_statement.out +0 -0
R kabel_test/test/runtime/logic.kab => kabel/test/runtime/logic.kab +0 -0
R kabel_test/test/runtime/logic.out => kabel/test/runtime/logic.out +0 -0
R kabel_test/test/runtime/turbo_oop.kab => kabel/test/runtime/turbo_oop.kab +0 -0
R kabel_test/test/runtime/turbo_oop.out => kabel/test/runtime/turbo_oop.out +0 -0
R kabel_test/test/syntax/assignment.kab => kabel/test/syntax/assignment.kab +0 -0
R kabel_test/test/syntax/assignment.out => kabel/test/syntax/assignment.out +0 -0
R kabel_test/test/syntax/function.kab => kabel/test/syntax/function.kab +0 -0
R kabel_test/test/syntax/function.out => kabel/test/syntax/function.out +0 -0
R kabel_test/test/syntax/if_else.kab => kabel/test/syntax/if_else.kab +0 -0
R kabel_test/test/syntax/if_else.out => kabel/test/syntax/if_else.out +0 -0
R kabel_test/test/syntax/no_semicolon.kab => kabel/test/syntax/no_semicolon.kab +0 -0
R kabel_test/test/syntax/no_semicolon.out => kabel/test/syntax/no_semicolon.out +0 -0
D kabel_test/Cargo.toml => kabel_test/Cargo.toml +0 -9
@@ 1,9 0,0 @@
-[package]
-name = "kabel_test"
-version = "0.1.0"
-edition = "2021"
-
-[dependencies]
-kabel = { path = "../kabel" }
-
-test_each_file = "0.3.3"