From f355183b8d44d34f88996f3c3ab17e4501f00d65 Mon Sep 17 00:00:00 2001 From: Natapat Samutpong Date: Sat, 5 Feb 2022 09:48:52 +0700 Subject: [PATCH] feat: `read` --- README.md | 1 + blspc/src/compiler/compile.rs | 5 ++++ blspc/src/vm/instr.rs | 14 ++++-------- blspc/src/vm/parser.rs | 2 +- blspc/src/vm/vm.rs | 43 ++++++++++++++++++++--------------- example/input.blsp | 4 ++++ 6 files changed, 40 insertions(+), 29 deletions(-) create mode 100644 example/input.blsp diff --git a/README.md b/README.md index 711a395..e3b7c0a 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ DONE: - Function definition: `fun` - Variable definition: `let` - Do blocks: `do` + - User input: `read` - Printing: `print` - Condition: `if` - Math: diff --git a/blspc/src/compiler/compile.rs b/blspc/src/compiler/compile.rs index 82031cb..418c25e 100644 --- a/blspc/src/compiler/compile.rs +++ b/blspc/src/compiler/compile.rs @@ -106,6 +106,11 @@ impl Compiler { result.push(Instr::Push { value: Type::Int(1) }); result.push(Instr::Call); }, + "read" => { + result.push(Instr::Push { value: Type::Int(0) }); // read doesn't need an argument + result.push(Instr::Push { value: Type::Int(2) }); + result.push(Instr::Call); + } "add" | "+" => { let mut lhs = self.compile_atom(&args[0])?; result.append(&mut lhs); diff --git a/blspc/src/vm/instr.rs b/blspc/src/vm/instr.rs index 0c6b93e..eed6af8 100644 --- a/blspc/src/vm/instr.rs +++ b/blspc/src/vm/instr.rs @@ -13,7 +13,6 @@ pub enum Type { } impl Type { - pub fn is_null(&self) -> bool { match self { Type::Null => true, @@ -102,10 +101,10 @@ impl Div for Type { impl Display for Type { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { - Type::Int(i) => write!(f, ":{}", i), - Type::Float(fl) => write!(f, ":{}", fl), - Type::Boolean(b) => write!(f, ":{}", b), - Type::String(s) => write!(f, "$\"{}\"", s), + Type::Int(i) => write!(f, "{}", i), + Type::Float(fl) => write!(f, "{}", fl), + Type::Boolean(b) => write!(f, "{}", b), + Type::String(s) => write!(f, "\"{}\"", s), _ => unreachable!(), } } @@ -115,11 +114,6 @@ impl FromStr for Type { type Err = String; fn from_str(s: &str) -> Result { - if !s.starts_with("$") && !s.starts_with(":") { - return Err(format!("Invalid literal: {}", s)); - } - - let s = &s[1..]; match s { "true" => Ok(Type::Boolean(true)), "false" => Ok(Type::Boolean(false)), diff --git a/blspc/src/vm/parser.rs b/blspc/src/vm/parser.rs index 90c4647..e0c2506 100644 --- a/blspc/src/vm/parser.rs +++ b/blspc/src/vm/parser.rs @@ -2,7 +2,7 @@ use regex::Regex; use crate::vm::instr::*; -const REGEX: &str = r###"[^\s\$";]+|\$"[^"]*"|;.*"###; +const REGEX: &str = r###"[^\s\$";]+|"[^"]*"|;.*"###; macro_rules! value { ($s:expr) => { $s.parse::().unwrap() }; } macro_rules! register { ($s:expr) => { $s.parse::().unwrap() }; } diff --git a/blspc/src/vm/vm.rs b/blspc/src/vm/vm.rs index d5da987..58027a6 100644 --- a/blspc/src/vm/vm.rs +++ b/blspc/src/vm/vm.rs @@ -1,4 +1,4 @@ -use std::fmt::Display; +use std::{io, fmt::Display}; use crate::vm::instr::{Instr::{self, *}, Type, Register}; @@ -81,7 +81,7 @@ impl VM { Call => { let index = &self.stack.pop().unwrap(); let args = &self.stack.pop().unwrap(); - call(index, args, self.instr_pointer)?; + self.call(index, args, self.instr_pointer)?; continue 'tco; }, Push { value } => { @@ -176,6 +176,29 @@ impl VM { } Err(Error::UnknownFunction(name)) } + + fn call(&mut self, index: &Type, args: &Type, line: isize) -> Result<(), Error> { + match index { + Type::Int(i) => { + match i { + 0 => Err(Error::UnknownFunctionCall(line, 0)), + 1 => { + print!("{}", args.fmt()); + Ok(()) + }, + 2 => { + let mut input = String::new(); + io::stdin().read_line(&mut input).unwrap(); + let input = input.trim().parse::().unwrap(); + self.stack.push(input); + Ok(()) + } + _ => Err(Error::UnknownFunctionCall(line, *i as isize)), + } + } + _ => {dbg!(index); Err(Error::UnknownFunctionCall(line, -1))}, + } + } } fn print_debug(vm: &VM, curr_instr: &Instr) { @@ -184,20 +207,4 @@ fn print_debug(vm: &VM, curr_instr: &Instr) { println!("regis: {:?}", regs); println!("stack: {:?}", vm.stack); println!("currn: {} {}", vm.instr_pointer, curr_instr); -} - -fn call(index: &Type, args: &Type, line: isize) -> Result<(), Error> { - match index { - Type::Int(i) => { - match i { - 0 => Err(Error::UnknownFunctionCall(line, 0)), - 1 => { - println!("{}", args.fmt()); - Ok(()) - }, - _ => Err(Error::UnknownFunctionCall(line, *i as isize)), - } - } - _ => {dbg!(index); Err(Error::UnknownFunctionCall(line, -1))}, - } } \ No newline at end of file diff --git a/example/input.blsp b/example/input.blsp new file mode 100644 index 0000000..22b8001 --- /dev/null +++ b/example/input.blsp @@ -0,0 +1,4 @@ +(fun main (do + (let in (read)) + (print "Your input was: ") + (print in)))