Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# The Compose Programming Language

```rust
# compose::test::assert_eval(r#"
println("'Hello, world' from Compose!");
# "#);
```

Compose is a functionally flavoured interpreted programming language with Rust-like syntax.
Expand Down Expand Up @@ -64,7 +62,7 @@ This should print `Hello, from Compose!` to the console.
### Run a file

```bash
compose file examples/hello.cmps
compose file hello.cmps
```

### Start a REPL
Expand All @@ -76,7 +74,7 @@ compose repl
Load a file in the REPL:

```bash
compose repl --from examples/prelude.cmps
compose repl --from prelude.cmps
```

### Explain an error
Expand Down
4 changes: 2 additions & 2 deletions compose-cli/src/file.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::error::CliError;
use crate::world::SystemWorld;
use crate::FileArgs;
use compose_eval::{EvalConfig, Machine};
use compose_eval::{Machine};
use compose_library::diag::Warned;
use crate::repl::print_tokens;

Expand All @@ -24,7 +24,7 @@ pub fn file(args: FileArgs) -> Result<(), CliError> {
crate::print_diagnostics(&world, &[], &warnings).unwrap();
}

let Warned { value, warnings } = compose_eval::eval_source(&source, &mut vm, &EvalConfig::default());
let Warned { value, warnings } = compose_eval::eval_source(&source, &mut vm);

if let Err(err) = value {
crate::print_diagnostics(&world, &err, &warnings).unwrap();
Expand Down
23 changes: 9 additions & 14 deletions compose-cli/src/repl/mod.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use crate::error::CliError;
use crate::repl::editor::{print_input, EditorFooter, EditorGutter, EditorHistory, EditorReader};
use crate::repl::editor::{EditorFooter, EditorGutter, EditorHistory, EditorReader, print_input};
use crate::world::SystemWorld;
use crate::{explain, ReplArgs};
use crate::{ReplArgs, explain};
use compose_editor::editor::Editor;
use compose_editor::renderer::full::CrosstermRenderer;
use compose_eval::{EvalConfig, Machine};
use compose_library::diag::{eco_format, Warned};
use compose_eval::Machine;
use compose_library::diag::{Warned, eco_format};
use compose_library::repr::Repr;
use compose_library::{Value, World};
use compose_syntax::{FileId, Lexer, Source, SyntaxKind};
use std::fs;
use compose_library::repr::Repr;

mod editor;

Expand Down Expand Up @@ -172,8 +172,7 @@ fn eval_initial_pass(vm: &mut Machine, world: &SystemWorld) {
// Evaluate every node in the source, printing any diagnostics along the way.
// Do not return early if there are any errors, as we want to print all diagnostics.
for i in 0..source.nodes().len() {
let Warned { value, warnings } =
compose_eval::eval_source_range(&source, i..i + 1, vm, &EvalConfig::default());
let Warned { value, warnings } = compose_eval::eval_source_range(&source, i..i + 1, vm);
crate::print_diagnostics(world, &[], &warnings).unwrap();
if let Err(err) = value {
crate::print_diagnostics(world, &err, &warnings).unwrap();
Expand All @@ -192,7 +191,7 @@ pub fn eval_repl_input(vm: &mut Machine, world: &SystemWorld, input: &str, args:

let source = entrypoint(world);
let len_after_edit = source.nodes().len();

if args.print_tokens {
print_tokens(input, source.id());
}
Expand All @@ -212,12 +211,8 @@ pub fn eval_repl_input(vm: &mut Machine, world: &SystemWorld, input: &str, args:
crate::print_diagnostics(world, &[], &syntax_warnings).unwrap();
}

let Warned { value, warnings } = compose_eval::eval_source_range(
&source,
len_before_edit..len_after_edit,
vm,
&EvalConfig::default(),
);
let Warned { value, warnings } =
compose_eval::eval_source_range(&source, len_before_edit..len_after_edit, vm);

if args.debug {
println!("{vm:#?}\n");
Expand Down
6 changes: 3 additions & 3 deletions compose-cli/src/world.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use compose_library::diag::{FileError, FileResult};
use compose_library::{library, Library, World};
use compose_library::{Library, World};
use compose_syntax::{FileId, Source};
use std::collections::HashMap;
use std::fmt::Debug;
Expand Down Expand Up @@ -53,7 +53,7 @@ impl SystemWorld {
sources: Mutex::new(sources),
entrypoint,
root,
library: library(),
library: Library::default(),
})
}

Expand All @@ -67,7 +67,7 @@ impl SystemWorld {
sources: Mutex::new(sources),
entrypoint,
root: PathBuf::new(),
library: library(),
library: Library::default(),
}
}

Expand Down
5 changes: 1 addition & 4 deletions compose-doc/src/realise.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::world::DocWorld;
use compose_eval::{EvalConfig, Machine};
use compose_eval::{Machine};
use compose_library::diag::{SourceDiagnostic, Warned};


Expand All @@ -10,9 +10,6 @@ pub(crate) fn eval_code(code: &str) -> EvalResult {
let Warned { value, warnings } = compose_eval::eval_source(
&world.source,
&mut vm,
&EvalConfig {
include_syntax_warnings: true,
},
);

let stdout = world.stdout.lock().expect("failed to lock stdout").clone();
Expand Down
4 changes: 2 additions & 2 deletions compose-doc/src/world.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::io::{Read, Write};
use std::sync::Mutex;
use compose_library::diag::FileResult;
use compose_library::{library, Library, World};
use compose_library::{Library, World};
use compose_syntax::{FileId, Source};

#[derive(Debug)]
Expand All @@ -28,7 +28,7 @@ impl DocWorld {

Self {
source,
library: library(),
library: Library::default(),
stdout: Mutex::new(String::new())
}
}
Expand Down
2 changes: 2 additions & 0 deletions compose-error-codes-doc-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ via `compose_doc::transform_markdown` into documented items with doc-tests.
*/

include!(concat!(env!("OUT_DIR"), "/Error_Codes"));

pub use compose_error_codes;
60 changes: 27 additions & 33 deletions compose-eval/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ pub mod test;
mod vm;

pub use crate::vm::Machine;
pub use evaluated::Evaluated;
use compose_library::diag::{error, SourceDiagnostic, SourceResult, Warned};
use compose_library::Value;
use compose_library::diag::{IntoSourceDiagnostic, SourceDiagnostic, SourceResult, Warned, error};
use compose_library::{Value, Vm};
use compose_syntax::ast::Statement;
use compose_syntax::Source;
use ecow::{eco_vec, EcoVec};
use compose_syntax::{Source, Span};
use ecow::{EcoVec, eco_vec};
pub use evaluated::Evaluated;
use std::cmp::min;
use std::ops::Range;

Expand Down Expand Up @@ -148,23 +148,27 @@ impl Eval for ast::Statement<'_> {
```
*/


pub trait Eval {
fn eval(self, vm: &mut Machine) -> SourceResult<Evaluated>;
}

#[derive(Default)]
pub struct EvalConfig {
/// Whether to include syntax warnings in the returned result.
pub include_syntax_warnings: bool,
}

pub fn eval_source(
source: &Source,
vm: &mut Machine,
eval_config: &EvalConfig,
) -> Warned<SourceResult<Value>> {
eval_source_range(source, 0..usize::MAX, vm, eval_config)
eval_source_range(source, 0..usize::MAX, vm)
}

pub fn eval(vm: &mut Machine) -> Warned<SourceResult<Value>> {
let entry_point = vm.engine().world.entry_point();
let source = match vm.engine().world.source(entry_point) {
Ok(source) => source,
Err(err) => {
return Warned::new(Err(eco_vec!(err.into_source_diagnostic(Span::detached()))));
}
};

eval_source(&source, vm)
}

/// Eval a source file.
Expand All @@ -174,7 +178,6 @@ pub fn eval_source_range(
source: &Source,
eval_range: Range<usize>,
vm: &mut Machine,
config: &EvalConfig,
) -> Warned<SourceResult<Value>> {
let mut result = Value::unit();

Expand All @@ -188,15 +191,11 @@ pub fn eval_source_range(
.map(|e| e.into())
.collect::<EcoVec<SourceDiagnostic>>();

let syntax_warnings = if config.include_syntax_warnings {
nodes
.iter()
.flat_map(|n| n.warnings())
.map(|e| e.into())
.collect::<EcoVec<SourceDiagnostic>>()
} else {
eco_vec![]
};
let syntax_warnings = nodes
.iter()
.flat_map(|n| n.warnings())
.map(|e| e.into())
.collect::<EcoVec<SourceDiagnostic>>();

if !errors.is_empty() {
return Warned::new(Err(errors)).with_warnings(syntax_warnings);
Expand All @@ -209,19 +208,17 @@ pub fn eval_source_range(
let span = node.span();
let err = error!(span, "expected a statement, found {:?}", node);

return build_err(&syntax_warnings, vm, eco_vec![err], config);
return build_err(&syntax_warnings, vm, eco_vec![err]);
}
};
result = match statement.eval(vm) {
Ok(value) => value.value,
Err(err) => return build_err(&syntax_warnings, vm, err, config),
Err(err) => return build_err(&syntax_warnings, vm, err),
}
}

let mut warnings = vm.sink_mut().take_warnings();
if config.include_syntax_warnings {
warnings.extend_from_slice(&syntax_warnings);
}
warnings.extend_from_slice(&syntax_warnings);

Warned::new(Ok(result)).with_warnings(warnings)
}
Expand All @@ -230,12 +227,9 @@ pub fn build_err(
syntax_warnings: &[SourceDiagnostic],
vm: &mut Machine,
errs: EcoVec<SourceDiagnostic>,
config: &EvalConfig,
) -> Warned<SourceResult<Value>> {
let mut warnings = vm.sink_mut().take_warnings();
if config.include_syntax_warnings {
warnings.extend_from_slice(syntax_warnings);
}
warnings.extend_from_slice(syntax_warnings);

Warned::new(Err(errs)).with_warnings(warnings)
}
4 changes: 2 additions & 2 deletions compose-eval/src/statement.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::evaluated::Evaluated;
use crate::vm::FlowEvent;
use crate::{Eval, EvalConfig, Machine, eval_source};
use crate::{Eval, Machine, eval_source};
use compose_library::diag::{SourceResult, Trace, TracePoint, Warned, bail, error};
use compose_syntax::ast::{AstNode, BreakStatement};
use compose_syntax::{FileId, ast};
Expand Down Expand Up @@ -117,7 +117,7 @@ impl Eval for ast::ModuleImport<'_> {

let module = vm
.with_frame(|vm| {
let Warned { value, warnings } = eval_source(&source, vm, &EvalConfig::default());
let Warned { value, warnings } = eval_source(&source, vm);
value?;
vm.sink_mut().warnings.extend(warnings);

Expand Down
9 changes: 3 additions & 6 deletions compose-eval/src/test/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::{EvalConfig, Machine};
use crate::{Machine};
use compose_error_codes::ErrorCode;
use compose_library::diag::compose_codespan_reporting::term::termcolor::{
ColorChoice, StandardStream,
};
use compose_library::diag::{FileError, FileResult, SourceDiagnostic, SourceResult, Warned, write_diagnostics, write_diagnostics_to_string};
use compose_library::{Library, Value, World, library};
use compose_library::{Library, Value, World, };
use compose_syntax::{FileId, Source};
use ecow::{EcoVec, eco_format, eco_vec};
use std::collections::HashMap;
Expand Down Expand Up @@ -64,7 +64,7 @@ impl TestWorld {
Self {
sources: Mutex::new(sources),
entrypoint,
library: library(),
library: Library::default(),
stdout: Mutex::new(String::new()),
}
}
Expand Down Expand Up @@ -163,9 +163,6 @@ pub fn eval_code_with_vm(vm: &mut Machine, world: &TestWorld, input: &str) -> Te
&source,
len_before_edit..len_after_edit,
vm,
&EvalConfig {
include_syntax_warnings: true,
},
);

TestResult {
Expand Down
Loading