Skip to content

Commit

Permalink
Added readline and flush intrinsics
Browse files Browse the repository at this point in the history
  • Loading branch information
jmeaster30 committed Nov 10, 2023
1 parent 3fc4d98 commit 97da487
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 3 deletions.
8 changes: 8 additions & 0 deletions examples/hydro/input.h2o
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module main
using std.io.read
main body
push string "prompt > "
push funcp std.io.read prompt
call
push funcp std.io.print println
call
3 changes: 1 addition & 2 deletions src/hydro/frontend/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -527,8 +527,7 @@ impl Parser {
_ => Err("Unexpected value for boolean type".to_string()),
},
"string" => {
let bytes = value_lexeme.clone().into_bytes().iter().skip(1).take(value_lexeme.len() - 2).map(|x| Value::Unsigned8(*x)).collect::<Vec<Value>>();
Ok(Value::Array(Array::create(Type::Unsigned8, Box::new(Value::Unsigned64((value_lexeme.len() - 2) as u64)), bytes)))
Ok(Value::string(value_lexeme[1..(value_lexeme.len()-1)].to_string()))
}
"u8" => match value_lexeme.parse::<u8>() {
Ok(value) => Ok(Value::Unsigned8(value)),
Expand Down
34 changes: 33 additions & 1 deletion src/hydro/intrinsic/intrinsicmanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ use crate::hydro::executioncontext::ExecutionContext;
use crate::hydro::value::Value;
use lazy_static::lazy_static;
use std::collections::HashMap;
use std::error::Error;
use std::io;
use std::io::Write;

// TODO This way kinda sucks a lot and the name implies it would handle code output for non-vm intrinsic functions

Expand All @@ -22,6 +25,8 @@ impl IntrinsicManager {

manager.add_map("print", print);
manager.add_map("println", println);
manager.add_map("flush", flush);
manager.add_map("readline", readline);

manager
}
Expand All @@ -31,7 +36,11 @@ impl IntrinsicManager {
}

pub fn call(&self, intrinsic_name: String, execution_context: &ExecutionContext, arguments: Vec<Value>) -> Result<Vec<Value>, Exception> {
self.mapping[&intrinsic_name](execution_context, arguments)
if self.mapping.contains_key(&intrinsic_name) {
self.mapping[&intrinsic_name](execution_context, arguments)
} else {
Err(Exception::new(execution_context.clone(), format!("Intrinsic '{}' is undefined :(", intrinsic_name).as_str()))
}
}
}

Expand All @@ -52,3 +61,26 @@ fn println(context: &ExecutionContext, args: Vec<Value>) -> Result<Vec<Value>, E
Ok(Vec::new())
}
}

fn flush(context: &ExecutionContext, args: Vec<Value>) -> Result<Vec<Value>, Exception> {
if args.len() != 0 {
Err(Exception::new(context.clone(), format!("Expected 0 arguments for readline but got {}", args.len()).as_str()))
} else {
match io::stdout().flush() {
Ok(()) => Ok(Vec::new()),
Err(io_error) => Err(Exception::new(context.clone(), io_error.to_string().as_str()))
}
}
}

fn readline(context: &ExecutionContext, args: Vec<Value>) -> Result<Vec<Value>, Exception> {
if args.len() != 0 {
Err(Exception::new(context.clone(), format!("Expected 0 arguments for readline but got {}", args.len()).as_str()))
} else {
let mut input = String::new();
match io::stdin().read_line(&mut input) {
Ok(_) => Ok(vec![Value::string(input)]),
Err(io_error) => Err(Exception::new(context.clone(), io_error.to_string().as_str()))
}
}
}
5 changes: 5 additions & 0 deletions src/hydro/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ pub enum Value {
}

impl Value {
pub fn string(value: String) -> Value {
let bytes = value.clone().into_bytes().iter().map(|x| Value::Unsigned8(*x)).collect::<Vec<Value>>();
Value::Array(Array::create(Type::Unsigned8, Box::new(Value::Unsigned64(value.len() as u64)), bytes))
}

pub fn type_of(&self) -> Type {
match self {
Value::Boolean(_) => Type::Boolean,
Expand Down
3 changes: 3 additions & 0 deletions standard_libraries/hydro/std/io/print.h2o
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ intrinsic print any body
intrinsic println any body
target vm "println"

intrinsic flush body
target vm "flush"

module main
using std.io.print
main body
Expand Down
16 changes: 16 additions & 0 deletions standard_libraries/hydro/std/io/read.h2o
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module std.io.read
using std.io.print
intrinsic readchar body
target vm "readchar"

intrinsic readline body
target vm "readline"

function prompt string body
push funcp std.io.print print
call
push funcp std.io.print flush
call
push funcp this readline
call
return

0 comments on commit 97da487

Please sign in to comment.