Skip to content

Commit

Permalink
added wait function so you can step through the program, kinda like a…
Browse files Browse the repository at this point in the history
… debug mode

ps: there are hashmaps now, but they dont work with strings yet (and other pointers as well)
  • Loading branch information
TomtheCoder2 committed Mar 26, 2024
1 parent 688d1f0 commit 5f9f36b
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 39 deletions.
2 changes: 2 additions & 0 deletions .idea/.gitignore

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

1 change: 1 addition & 0 deletions .idea/clox_rs.iml

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "phoenix-lang"
description = "A simple, fast programming language"
version = "1.3.2"
version = "1.4.0"
edition = "2021"
license = "MIT"
repository = "https://github.com/TomtheCoder2/phoenix"
Expand Down
6 changes: 6 additions & 0 deletions phoenix_examples/wait_test.phx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
print(1);
print(2);
print(3);
print(4);
print(5);
print(6);
4 changes: 3 additions & 1 deletion src/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ pub enum OpCode {
// Push the string on the stack to the heap and replace it with a pointer to the heap
OpCreateString,
/// Creates a hashmap of the last 2n items, where the first value is the key and the second one is the value
OpCreateHashMap(usize)
OpCreateHashMap(usize),
/// Waits until enter is pressed before continuing
OpWait,
}

#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
Expand Down
33 changes: 31 additions & 2 deletions src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ pub struct Compiler {
panic_mode: bool,
quiet_mode: bool,
debug_mode: bool,
/// Means that before each line is executed, the VM will wait for user input
wait_mode: bool,
}

impl Compiler {
Expand Down Expand Up @@ -131,8 +133,30 @@ impl Compiler {
&self.current_code_module_ref().tokens[self.current_code_module_ref().tokens.len() - 1]
}

// also adds the opWait code if the token_type is a semicolon
fn consume(&mut self, token_type: TokenType, msg: &str) {
self.advance();
if self.previous().token_type == TokenType::Semicolon {
if self.wait_mode {
let file = self.current_module().scanner.file.clone();
let line = self.current_module().scanner.cur_line;
let s = format!(
"{}:{}: {}",
file, line,
self.current_module()
.scanner
.code
.split("\n")
.collect::<Vec<&str>>()
.iter()
.nth(line - 1)
.unwrap()
);
self.emit_constant(Value::PhoenixString(s));
self.emit_instr(OpCreateString);
self.emit_instr(OpWait);
}
}
if !(self.previous().token_type == token_type) {
self.error(msg);
}
Expand Down Expand Up @@ -1280,6 +1304,7 @@ impl Compiler {
quiet,
start_line,
false,
false,
)
}

Expand All @@ -1289,6 +1314,7 @@ impl Compiler {
quiet: bool,
start_line: usize,
debug_mode: bool,
wait_mode: bool,
) -> Compiler {
let mut compiler = Compiler {
modules: vec![CompilerModuleChunk::new(
Expand All @@ -1306,6 +1332,7 @@ impl Compiler {
panic_mode: false,
quiet_mode: quiet,
debug_mode,
wait_mode,
};
compiler.new_start(file, code, quiet, start_line, 0);
compiler
Expand Down Expand Up @@ -1390,8 +1417,9 @@ impl Compiler {
}
}

pub fn compile_code(code: String, debug: bool) -> Option<CompilationResult> {
let mut compiler = Compiler::new_file(DEFAULT_FILE_NAME.to_string(), code, false, 0, debug);
pub fn compile_code(code: String, debug: bool, wait: bool) -> Option<CompilationResult> {
let mut compiler =
Compiler::new_file(DEFAULT_FILE_NAME.to_string(), code, false, 0, debug, wait);
compiler.compile(debug)
}
}
Expand All @@ -1409,6 +1437,7 @@ impl Clone for Compiler {
panic_mode: self.panic_mode,
quiet_mode: self.quiet_mode,
debug_mode: false,
wait_mode: self.wait_mode,
}
}
}
Expand Down
21 changes: 14 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use rustyline::config::Configurer;
use std::fs::File;
use std::io::Read;
use std::path::Path;
Expand Down Expand Up @@ -36,8 +37,8 @@ pub enum InterpretResult {

pub const VERSION: &str = env!("CARGO_PKG_VERSION");

pub fn fly(file: String, source: String, debug: bool, quiet: bool) -> InterpretResult {
let mut compiler = Compiler::new_file(file, source, quiet, 0, DEBUG);
pub fn fly(file: String, source: String, debug: bool, quiet: bool, wait: bool) -> InterpretResult {
let mut compiler = Compiler::new_file(file, source, quiet, 0, DEBUG, wait);
let result = compiler.compile(debug);
if result.is_none() {
return InterpretResult::InterpretCompileError;
Expand Down Expand Up @@ -70,19 +71,21 @@ pub fn repl() -> Result<(), ReadlineError> {
);
let mut state: Option<VMState> = None;
let mut modules = Vec::new();
let mut compiler = Compiler::new_file(file_name, s.clone(), false, 0, DEBUG);
let mut compiler = Compiler::new_file(file_name, s.clone(), false, 0, DEBUG, false);
let mut last_state;
let mut last_compiler;
let mut current_prompt = ">>";
let default_prompt = ">>";
let mut current_line = "".to_string();
// tracks how many blocks deep we are (and thus how many spaces to indent)
let mut block_offset=0;
let mut block_offset = 0;
loop {
// let readline = rl.readline(" \x1b[32m>>\x1b[0m");
let readline = rl.readline_with_initial(current_prompt, (&*" ".repeat(block_offset), ""));
match readline {
Ok(mut line) => {
rl.set_max_history_size(10000)
.expect("failed to set max history size");
rl.add_history_entry(line.as_str())
.expect("failed to add history");
line.push('\n');
Expand Down Expand Up @@ -113,7 +116,11 @@ pub fn repl() -> Result<(), ReadlineError> {
// let _result = fly(file_name.clone(), line, DEBUG, false);
// dbg!(&compiler.current_module().scanner.code);

compiler.current_module().scanner.code.push_str(&current_line);
compiler
.current_module()
.scanner
.code
.push_str(&current_line);
current_line = "".to_string();
block_offset = 0;
// dbg!(&compiler.current_module().scanner.code);
Expand Down Expand Up @@ -179,7 +186,7 @@ pub fn repl() -> Result<(), ReadlineError> {
Ok(())
}

pub fn run_file(filename: String, debug: bool) -> InterpretResult {
pub fn run_file(filename: String, debug: bool, wait: bool) -> InterpretResult {
let path = Path::new(&filename);
let path_display = path.display();

Expand All @@ -193,7 +200,7 @@ pub fn run_file(filename: String, debug: bool) -> InterpretResult {

let mut s = String::new();
match file.read_to_string(&mut s) {
Ok(_) => fly(filename, s, debug, false),
Ok(_) => fly(filename, s, debug, false, wait),
Err(why) => {
eprintln!("Failed to read {}: {}", path_display, why);
exit(1);
Expand Down
36 changes: 23 additions & 13 deletions src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ use crate::{error, info, repl, run_file, DEBUG};

#[derive(Parser, Debug)]
#[command(
author,
version,
about,
long_about = "The compiler and interpreter for the phoenix programming language.\n\n\
author,
version,
about,
long_about = "The compiler and interpreter for the phoenix programming language.\n\n\
To simply interpret a file, give it as the [input file] parameter.\n
To compile to a phc file, specify an output file with the output-file flag.\n
To start the REPL, simply dont provide any arguments.\n"
Expand All @@ -42,6 +42,9 @@ enum Commands {
Run {
/// The file to run
file: String,
/// Wait for use input before running each statement
#[arg(short, long, action)]
wait: bool,
},
/// Build a file
Build {
Expand Down Expand Up @@ -79,8 +82,8 @@ pub fn main() {
}
compile(file, output_file, debug);
}
Commands::Run { file } => {
run_f(file);
Commands::Run { file, wait } => {
run_f(file, wait);
}
}
} else if cli.file.is_none() {
Expand All @@ -93,14 +96,14 @@ pub fn main() {
}
exit(0);
} else {
run_f(cli.file.unwrap());
run_f(cli.file.unwrap(), false);
}
}

fn run_f(file: String) {
fn run_f(file: String, wait: bool) {
// check if the file ends in .phx
if file.ends_with(".phx") {
run_file(file, DEBUG);
run_file(file, DEBUG, wait);
} else {
compiled_run(file);
}
Expand Down Expand Up @@ -141,7 +144,7 @@ fn compile(input_file: String, actual_output_file: String, debug: bool) {
exit(64);
}
};
let mut compiler = Compiler::new_file(file_name, code.clone(), true, 0, debug);
let mut compiler = Compiler::new_file(file_name, code.clone(), true, 0, debug, false);
let res = if let Some(res) = compiler.compile(debug) {
res
} else {
Expand All @@ -159,9 +162,16 @@ fn compile(input_file: String, actual_output_file: String, debug: bool) {
info!("Size after compression: {} bytes", compressed_data.len());
if DEBUG {
info!("data: {:?}", compressed_data);
#[cfg(feature = "debug")]{
write_to_file(&format!("{}.toml", &actual_output_file), toml::to_string(&res).unwrap().as_bytes().to_vec());
write_to_file(&format!("{}.ron", &actual_output_file), ron::to_string(&res).unwrap().as_bytes().to_vec());
#[cfg(feature = "debug")]
{
write_to_file(
&format!("{}.toml", &actual_output_file),
toml::to_string(&res).unwrap().as_bytes().to_vec(),
);
write_to_file(
&format!("{}.ron", &actual_output_file),
ron::to_string(&res).unwrap().as_bytes().to_vec(),
);
}
}
info!("Size of code: {} bytes", code.len());
Expand Down
6 changes: 5 additions & 1 deletion src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,11 @@ impl HeapObjVal {
"{{{}}}",
map.map
.iter()
.map(|(k, v)| format!("{}: {}", k.to_string(vm, state, modules), v.to_string(vm, state, modules)))
.map(|(k, v)| format!(
"{}: {}",
k.to_string(vm, state, modules),
v.to_string(vm, state, modules)
))
.collect::<Vec<String>>()
.join(", ")
),
Expand Down
Loading

0 comments on commit 5f9f36b

Please sign in to comment.