Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add reader trait #569

Merged
merged 3 commits into from
May 22, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 101 additions & 72 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,18 @@ libloading = { version = "0.7", optional = true }
lazy_static = "1.4"

[features]
default = ["repl", "ffi"]
default = ["repl", "ffi", "std"]
repl = ["linefeed"]
ffi = ["libloading", "libffi"]
std = []

[dev-dependencies]
libc = "0.2"

[[bin]]
name = "jinko"
path = "interpreter/jinko.rs"
required-features = ["std"]

[profile.release]
lto = true
3 changes: 2 additions & 1 deletion examples/simple-repl.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use jinko::context::Context;
use jinko::io_trait::JkStdReader;
use std::io::{self, Result, Write};

fn main() -> Result<()> {
let stdin = io::stdin();
let mut stdout = io::stdout();

let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(JkStdReader {}));
CohenArthur marked this conversation as resolved.
Show resolved Hide resolved
let mut input = String::new();

let mut prompt = "> ";
Expand Down
2 changes: 1 addition & 1 deletion interpreter/jinko.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ fn run_tests(ctx: &mut Context) -> Result<Option<ObjectInstance>, Error> {
fn handle_input(args: &Args, file: &Path) -> InteractResult {
let input = fs::read_to_string(file)?;

let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(jinko::io_trait::JkStdReader {}));

if !args.nostdlib() {
ctx.init_stdlib()?;
Expand Down
2 changes: 1 addition & 1 deletion interpreter/repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl Repl {
pub fn launch(self) -> InteractResult {
let mut ctx = match self.ctx {
Some(ctx) => ctx,
None => Context::new(),
None => Context::new(Box::new(jinko::io_trait::JkStdReader {})),
};

Repl::setup_context(&mut ctx);
Expand Down
23 changes: 9 additions & 14 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::builtins::Builtins;
use crate::error::{ErrKind, Error, ErrorHandler};
use crate::instance::ObjectInstance;
use crate::instruction::{Block, FunctionDec, FunctionKind, Instruction, TypeDec, Var};
use crate::io_trait::JkReader;
use crate::parser;
use crate::typechecker::CheckedType;
use crate::typechecker::{SpecializedNode, TypeCheck, TypeCtx, TypeId};
Expand Down Expand Up @@ -62,12 +63,6 @@ pub struct Context {
pub error_handler: ErrorHandler,
}

impl Default for Context {
fn default() -> Context {
Context::new()
}
}

impl Context {
fn new_entry() -> FunctionDec {
let mut ep = FunctionDec::new(String::from(ENTRY_NAME), None, vec![], vec![]);
Expand All @@ -79,7 +74,7 @@ impl Context {
}

/// Create a new empty context without the standard library
pub fn new() -> Context {
pub fn new(reader: Box<dyn JkReader>) -> Context {
let mut ctx = Context {
path: None,
args: Vec::new(),
Expand All @@ -89,7 +84,7 @@ impl Context {
#[cfg(feature = "ffi")]
external_libs: Vec::new(),
scope_map: ScopeMap::new(),
typechecker: TypeCtx::new(),
typechecker: TypeCtx::new(reader),
debug_mode: false,
code: None,
entry_point: Self::new_entry(),
Expand Down Expand Up @@ -426,7 +421,7 @@ mod tests {
let f0 = FunctionDec::new("f0".to_owned(), None, vec![], vec![]);
let f0_copy = FunctionDec::new("f0".to_owned(), None, vec![], vec![]);

let mut i = Context::new();
let mut i = Context::new(Box::new(crate::io_trait::JkStdReader {}));

assert_eq!(i.add_function(f0), Ok(()));
assert!(i.add_function(f0_copy).is_err());
Expand All @@ -437,15 +432,15 @@ mod tests {
let v0 = Var::new("v0".to_owned());
let v0_copy = Var::new("v0".to_owned());

let mut i = Context::new();
let mut i = Context::new(Box::new(crate::io_trait::JkStdReader {}));

assert_eq!(i.add_variable(v0), Ok(()));
assert!(i.add_variable(v0_copy).is_err());
}

#[test]
fn t_print_scopemap() {
let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(crate::io_trait::JkStdReader {}));
ctx.init_stdlib().unwrap();
ctx.execute().unwrap();

Expand All @@ -458,7 +453,7 @@ mod tests {

#[test]
fn t_print_eb() {
let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(crate::io_trait::JkStdReader {}));

ctx.add_variable(Var::new(String::from("a_var_named_a")))
.unwrap();
Expand All @@ -480,7 +475,7 @@ mod tests {

#[test]
fn t_eval() {
let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(crate::io_trait::JkStdReader {}));
let input = String::from("my_var = 1");

ctx.eval(&input).unwrap();
Expand All @@ -491,7 +486,7 @@ mod tests {

#[test]
fn t_double_eval() {
let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(crate::io_trait::JkStdReader {}));

let mut input = String::from("my_var = 1");
ctx.eval(&input).unwrap();
Expand Down
3 changes: 2 additions & 1 deletion src/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ mod tests {

#[test]
fn create_map_different_size() {
let mut ctx = TypeCtx::new();
use crate::io_trait::JkStdReader;
let mut ctx = TypeCtx::new(Box::new(JkStdReader {}));

assert!(GenericMap::create(&[ty!("int"), ty!("float")], &[ty!("T")], &mut ctx).is_err());
}
Expand Down
2 changes: 1 addition & 1 deletion src/instance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ mod tests {
use crate::value::JkInt;

fn setup() -> Context {
let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(crate::io_trait::JkStdReader {}));

let inst = constructs::expr(span!("type Point(x: int, y: int);"))
.unwrap()
Expand Down
8 changes: 4 additions & 4 deletions src/instruction/binary_op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ mod tests {
Operator::new("-"),
);

let mut i = Context::new();
let mut i = Context::new(Box::new(crate::io_trait::JkStdReader {}));

assert_eq!(
binary_op.rhs().execute(&mut i).unwrap(),
Expand All @@ -225,7 +225,7 @@ mod tests {
Operator::new("-"),
);

let mut i = Context::new();
let mut i = Context::new(Box::new(crate::io_trait::JkStdReader {}));

assert_eq!(binary_op.operator(), Operator::Sub);

Expand All @@ -243,7 +243,7 @@ mod tests {
let boxed_output = crate::parser::constructs::expr(input).unwrap().1;
let output = boxed_output.downcast_ref::<BinaryOp>().unwrap();

let mut i = Context::new();
let mut i = Context::new(Box::new(crate::io_trait::JkStdReader {}));

assert_eq!(
output.execute(&mut i).unwrap(),
Expand Down Expand Up @@ -305,7 +305,7 @@ mod tests {

macro_rules! binop_assert {
($expr:expr) => {{
let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(crate::io_trait::JkStdReader {}));
let expr = crate::parser::constructs::expr(nom_locate::LocatedSpan::new_extra(
stringify!($expr),
None,
Expand Down
8 changes: 4 additions & 4 deletions src/instruction/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ mod tests {
fn block_execute_empty() {
let b = Block::new();

let mut i = Context::new();
let mut i = Context::new(Box::new(crate::io_trait::JkStdReader {}));

assert_eq!(b.execute(&mut i), None);
assert!(!i.error_handler.has_errors());
Expand All @@ -233,7 +233,7 @@ mod tests {
];
b.set_instructions(instr);

let mut i = Context::new();
let mut i = Context::new(Box::new(crate::io_trait::JkStdReader {}));

assert_eq!(b.execute(&mut i), None);
assert!(!i.error_handler.has_errors());
Expand All @@ -253,7 +253,7 @@ mod tests {
b.add_instruction(last);
b.set_statement(false);

let mut i = Context::new();
let mut i = Context::new(Box::new(crate::io_trait::JkStdReader {}));

assert_eq!(b.execute(&mut i).unwrap(), JkInt::from(18).to_instance());
assert!(!i.error_handler.has_errors());
Expand All @@ -269,7 +269,7 @@ mod tests {
.unwrap()
.1;

let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(crate::io_trait::JkStdReader {}));

assert_eq!(ctx.type_check(b.as_mut()).unwrap(), CheckedType::Void)
}
Expand Down
2 changes: 1 addition & 1 deletion src/instruction/field_access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ mod tests {
#[test]
#[ignore] // FIXME: Do not ignore once we can type instance fields
fn t_valid_multi_field_access() {
let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(crate::io_trait::JkStdReader {}));

let inst = constructs::expr(span!("type Pair1(x: int, y: int)"))
.unwrap()
Expand Down
6 changes: 3 additions & 3 deletions src/instruction/function_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ mod tests {
use crate::instance::ToObjectInstance;
use crate::value::JkInt;

let mut i = Context::new();
let mut i = Context::new(Box::new(crate::io_trait::JkStdReader {}));
let func_dec = constructs::expr(span!("func __second(f: int, s: int) -> int { s }"))
.unwrap()
.1;
Expand All @@ -467,7 +467,7 @@ mod tests {
use crate::instance::ToObjectInstance;
use crate::value::JkInt;

let mut i = Context::new();
let mut i = Context::new(Box::new(crate::io_trait::JkStdReader {}));
let func_dec = constructs::expr(span!("func add(a: int, b: int) -> int { a + b }"))
.unwrap()
.1;
Expand All @@ -486,7 +486,7 @@ mod tests {
use crate::instance::ToObjectInstance;
use crate::value::JkInt;

let mut i = Context::new();
let mut i = Context::new(Box::new(crate::io_trait::JkStdReader {}));
let func_dec = constructs::expr(span!("func one() -> int { one = 1; one }"))
.unwrap()
.1;
Expand Down
6 changes: 3 additions & 3 deletions src/instruction/function_declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ mod tests {
FunctionDec::new("fn".to_owned(), Some(TypeId::from("int")), vec![], vec![]);
function.set_kind(FunctionKind::Ext);

let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(crate::io_trait::JkStdReader {}));

assert_eq!(ctx.type_check(&mut function).unwrap(), CheckedType::Void);
assert!(!ctx.error_handler.has_errors());
Expand All @@ -441,7 +441,7 @@ mod tests {
let block = constructs::block(span!("{ 15 }")).unwrap().1;
function.set_block(block);

let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(crate::io_trait::JkStdReader {}));

assert_eq!(ctx.type_check(&mut function).unwrap(), CheckedType::Void);
assert!(!ctx.error_handler.has_errors());
Expand All @@ -460,7 +460,7 @@ mod tests {
let block = constructs::block(span!("{ 15 }")).unwrap().1;
function.set_block(block);

let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(crate::io_trait::JkStdReader {}));

assert!(ctx.type_check(&mut function).is_err());
assert!(ctx.error_handler.has_errors());
Expand Down
4 changes: 2 additions & 2 deletions src/instruction/if_else.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ mod tests {
use crate::instance::ToObjectInstance;
use crate::value::{JkBool, JkInt};

let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(crate::io_trait::JkStdReader {}));

let mut if_block = Block::new();
let mut else_block = Block::new();
Expand All @@ -225,7 +225,7 @@ mod tests {
use crate::instance::ToObjectInstance;
use crate::value::{JkBool, JkInt};

let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(crate::io_trait::JkStdReader {}));

let mut if_block = Block::new();
let mut else_block = Block::new();
Expand Down
13 changes: 9 additions & 4 deletions src/instruction/incl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::error::{ErrKind, Error};
use crate::generics::GenericUser;
use crate::instance::ObjectInstance;
use crate::instruction::{InstrKind, Instruction};
use crate::io_trait::JkReader;
use crate::location::SpanTuple;
use crate::parser::constructs;
use crate::typechecker::{CheckedType, TypeCheck, TypeCtx};
Expand Down Expand Up @@ -42,8 +43,12 @@ impl Incl {
}
}

fn fetch_instructions(&self, formatted: &Path) -> Result<Vec<Box<dyn Instruction>>, Error> {
let input = std::fs::read_to_string(&formatted)?;
fn fetch_instructions(
&self,
formatted: &Path,
reader: &dyn JkReader,
) -> Result<Vec<Box<dyn Instruction>>, Error> {
let input = reader.read_to_string(formatted.to_str().unwrap())?;
CohenArthur marked this conversation as resolved.
Show resolved Hide resolved

// We can't just parse the input, since it adds the instructions
// to an entry block in order to execute them. What we can do, is
Expand Down Expand Up @@ -192,7 +197,7 @@ impl TypeCheck for Incl {
return CheckedType::Void;
}

let instructions = match self.fetch_instructions(&final_path) {
let instructions = match self.fetch_instructions(&final_path, ctx.reader()) {
Ok(instructions) => instructions,
Err(e) => {
ctx.error(e);
Expand Down Expand Up @@ -239,7 +244,7 @@ mod tests {

#[test]
fn tc_typecheck_stdlib() {
let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(crate::io_trait::JkStdReader {}));
ctx.execute().unwrap();
}

Expand Down
2 changes: 1 addition & 1 deletion src/instruction/method_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ mod tests {

#[test]
fn t_execute() {
let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(crate::io_trait::JkStdReader {}));
let mut func_dec = constructs::expr(span!("func __first(a: int, b: int) -> int { a }"))
.unwrap()
.1;
Expand Down
4 changes: 2 additions & 2 deletions src/instruction/type_instantiation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ mod test {
use crate::typechecker::TypeId;
use crate::value::JkInt;

let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(crate::io_trait::JkStdReader {}));

// Create a new type with two integers fields
let fields = vec![
Expand Down Expand Up @@ -339,7 +339,7 @@ mod test {

const TYPE_NAME: &str = "Type_Name";

let mut ctx = Context::new();
let mut ctx = Context::new(Box::new(crate::io_trait::JkStdReader {}));

// Create a new type with two integers fields
let fields = vec![
Expand Down
2 changes: 1 addition & 1 deletion src/instruction/var.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ mod tests {

#[test]
fn keep_instance() {
let mut i = Context::new();
let mut i = Context::new(Box::new(crate::io_trait::JkStdReader {}));
let mut v = Var::new("a".to_string());

let instance = JkInt::from(15).to_instance();
Expand Down
Loading