Compare commits

..

No commits in common. "56196551b89426633e754201c8f70b61093af32e" and "a4b9b958e99b671c5899e9a16467a3581b405a04" have entirely different histories.

5 changed files with 137 additions and 292 deletions

View File

@ -1,43 +0,0 @@
use codespan_reporting::diagnostic::Label;
use dmc_lib::diagnostic::Diagnostic;
pub fn to_csr_diagnostic(
file_id: usize,
diagnostic: &Diagnostic,
) -> codespan_reporting::diagnostic::Diagnostic<usize> {
let mut primary_label = Label::primary(file_id, diagnostic.start()..diagnostic.end());
if let Some(primary_label_message) = diagnostic.primary_label_message() {
primary_label = primary_label.with_message(primary_label_message);
}
let secondary_labels: Vec<Label<usize>> = diagnostic
.secondary_labels()
.iter()
.map(|secondary_label| {
let mut label =
Label::secondary(file_id, secondary_label.start()..secondary_label.end());
if let Some(message) = secondary_label.message() {
label = label.with_message(message);
}
label
})
.collect();
let mut csr_diagnostic = codespan_reporting::diagnostic::Diagnostic::error()
.with_message(diagnostic.message())
.with_label(primary_label)
.with_labels(secondary_labels);
if let Some(error_code) = diagnostic.error_code() {
csr_diagnostic = csr_diagnostic.with_code(format!("E{:04}", error_code));
}
if let Some((reporter_file, reporter_line)) = diagnostic.reporter() {
csr_diagnostic = csr_diagnostic.with_note(format!(
"Reported by (Rust) source: {}, line {}",
reporter_file, reporter_line
));
}
csr_diagnostic
}

View File

@ -1,11 +1,9 @@
mod common;
mod repl;
mod run;
use crate::repl::repl;
use crate::run::compile_and_run_script;
use clap::{Parser, Subcommand};
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
use std::io;
use std::path::PathBuf;
@ -49,7 +47,7 @@ fn main() {
repl(
&mut io::stdin().lock(),
&mut io::stdout().lock(),
&mut StandardStream::stderr(ColorChoice::Always),
&mut io::stderr().lock(),
register_count,
);
}

View File

@ -1,6 +1,3 @@
use crate::common::to_csr_diagnostic;
use codespan_reporting::files::SimpleFiles;
use codespan_reporting::term::{Config, WriteStyle, emit_to_write_style};
use dmc_lib::SyntheticFunctionSession;
use dmc_lib::constants_table::ConstantsTable;
use dmc_lib::diagnostic::Diagnostics;
@ -14,13 +11,9 @@ use std::io::{BufRead, Write};
pub fn repl(
read: &mut impl BufRead,
out: &mut impl Write,
err: &mut impl WriteStyle,
err: &mut impl Write,
register_count: usize,
) {
let diagnostics_config = Config::default();
let mut files: SimpleFiles<&str, String> = SimpleFiles::new();
let mut current_file_id;
let mut buffer = String::new();
let mut session = SyntheticFunctionSession::new("__repl");
@ -55,10 +48,8 @@ pub fn repl(
.insert(function.name_owned(), function);
}
Err(diagnostics) => {
current_file_id = files.add("input", String::from(input));
for diagnostic in diagnostics {
let csr_diagnostic = to_csr_diagnostic(current_file_id, &diagnostic);
emit_to_write_style(err, &diagnostics_config, &files, &csr_diagnostic).unwrap();
writeln!(err, "{}", diagnostic.message()).unwrap();
}
buffer.clear();
continue 'repl;

View File

@ -1,4 +1,4 @@
use crate::common::to_csr_diagnostic;
use codespan_reporting::diagnostic::Label;
use codespan_reporting::files::SimpleFiles;
use codespan_reporting::term;
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
@ -88,7 +88,43 @@ fn report_and_exit(
let writer = StandardStream::stderr(ColorChoice::Always);
let config = term::Config::default();
for diagnostic in diagnostics {
let csr_diagnostic = to_csr_diagnostic(script_file_id, diagnostic);
let mut primary_label =
Label::primary(script_file_id, diagnostic.start()..diagnostic.end());
if let Some(primary_label_message) = diagnostic.primary_label_message() {
primary_label = primary_label.with_message(primary_label_message);
}
let secondary_labels: Vec<Label<usize>> = diagnostic
.secondary_labels()
.iter()
.map(|secondary_label| {
let mut label = Label::secondary(
script_file_id,
secondary_label.start()..secondary_label.end(),
);
if let Some(message) = secondary_label.message() {
label = label.with_message(message);
}
label
})
.collect();
let mut csr_diagnostic = codespan_reporting::diagnostic::Diagnostic::error()
.with_message(diagnostic.message())
.with_label(primary_label)
.with_labels(secondary_labels);
if let Some(error_code) = diagnostic.error_code() {
csr_diagnostic = csr_diagnostic.with_code(format!("E{:04}", error_code));
}
if let Some((reporter_file, reporter_line)) = diagnostic.reporter() {
csr_diagnostic = csr_diagnostic.with_note(format!(
"Reported by (Rust) source: {}, line {}",
reporter_file, reporter_line
));
}
term::emit_to_write_style(&mut writer.lock(), &config, files, &csr_diagnostic).unwrap();
}
if diagnostics.len() == 1 {

View File

@ -62,7 +62,7 @@ pub fn parse_statement(input: &str) -> ParseResult<Option<Statement>> {
(statement, diagnostics)
}
pub fn parse_expression(input: &str) -> ParseResult<Option<Expression>> {
pub fn parse_expression(input: &str) -> ParseResult<Expression> {
let mut parser = Parser::new(input);
let mut diagnostics = Vec::new();
diagnostics.append(&mut parser.advance());
@ -918,9 +918,9 @@ impl<'a> Parser<'a> {
let initializer = if self.current.is_some() && self.peek_current(TokenKind::Equals) {
diagnostics.append(&mut self.advance()); // equals
let (maybe_expression, mut ds) = self.expression();
let (expression, mut ds) = self.expression();
diagnostics.append(&mut ds);
maybe_expression
Some(expression)
} else {
None
};
@ -961,7 +961,10 @@ impl<'a> Parser<'a> {
Some(let_statement) => (Some(Statement::Let(let_statement)), diagnostics),
}
}
_ => self.expression_statement_or_assign_statement(),
_ => {
let (statement, diagnostics) = self.expression_statement_or_assign_statement();
(Some(statement), diagnostics)
}
}
}
@ -984,100 +987,65 @@ impl<'a> Parser<'a> {
let (_, mut ds) = self.expect_advance(TokenKind::Equals);
diagnostics.append(&mut ds);
let (maybe_expression, mut ds) = self.expression();
let (expression, mut ds) = self.expression();
diagnostics.append(&mut ds);
let identifier = match maybe_identifier {
Some(identifier) => identifier,
None => {
return (None, diagnostics);
}
};
let expression = match maybe_expression {
Some(expression) => expression,
None => {
return (None, diagnostics);
}
};
let let_statement = LetStatement::new(
self.next_node_id(),
self.token_text(&identifier),
SourceRange::new(identifier.start(), identifier.end()),
is_mut,
expression,
);
(Some(let_statement), diagnostics)
}
fn expression_statement_or_assign_statement(&mut self) -> ParseResult<Option<Statement>> {
let mut diagnostics = Vec::new();
let (maybe_base, mut ds) = self.expression();
diagnostics.append(&mut ds);
let base = match maybe_base {
Some(base) => base,
None => {
return (None, diagnostics);
}
};
if self.current.is_some() && self.peek_current(TokenKind::Equals) {
let (maybe_assign_statement, mut ds) = self.assign_rhs(base);
diagnostics.append(&mut ds);
if let Some(assign_statement) = maybe_assign_statement {
(Some(Statement::Assign(assign_statement)), diagnostics)
} else {
(None, diagnostics)
}
} else {
(
Some(Statement::Expression(ExpressionStatement::new(base))),
diagnostics,
)
}
}
fn assign_rhs(&mut self, destination: Expression) -> ParseResult<Option<AssignStatement>> {
let mut diagnostics = Vec::new();
let (_, mut ds) = self.expect_advance(TokenKind::Equals);
diagnostics.append(&mut ds);
let (maybe_value, mut ds) = self.expression();
diagnostics.append(&mut ds);
if let Some(value) = maybe_value {
(Some(AssignStatement::new(destination, value)), diagnostics)
if let Some(identifier) = maybe_identifier {
let let_statement = LetStatement::new(
self.next_node_id(),
self.token_text(&identifier),
SourceRange::new(identifier.start(), identifier.end()),
is_mut,
expression,
);
(Some(let_statement), diagnostics)
} else {
(None, diagnostics)
}
}
fn expression(&mut self) -> ParseResult<Option<Expression>> {
fn expression_statement_or_assign_statement(&mut self) -> ParseResult<Statement> {
let mut diagnostics = Vec::new();
let (base, mut ds) = self.expression();
diagnostics.append(&mut ds);
if self.current.is_some() && self.peek_current(TokenKind::Equals) {
let (assign_statement, mut ds) = self.assign_rhs(base);
diagnostics.append(&mut ds);
(Statement::Assign(assign_statement), diagnostics)
} else {
(
Statement::Expression(ExpressionStatement::new(base)),
diagnostics,
)
}
}
fn assign_rhs(&mut self, destination: Expression) -> ParseResult<AssignStatement> {
let mut diagnostics = Vec::new();
let (_, mut ds) = self.expect_advance(TokenKind::Equals);
diagnostics.append(&mut ds);
let (value, mut ds) = self.expression();
diagnostics.append(&mut ds);
(AssignStatement::new(destination, value), diagnostics)
}
fn expression(&mut self) -> ParseResult<Expression> {
self.bitwise_or_expression()
}
fn bitwise_or_expression(&mut self) -> ParseResult<Option<Expression>> {
fn bitwise_or_expression(&mut self) -> ParseResult<Expression> {
let mut diagnostics = Vec::new();
let (maybe_base, mut ds) = self.bitwise_xor_expression();
let (mut base, mut ds) = self.bitwise_xor_expression();
diagnostics.append(&mut ds);
let mut base = match maybe_base {
Some(base) => base,
None => {
return (None, diagnostics);
}
};
while self.current.is_some() && self.peek_current(TokenKind::Bar) {
diagnostics.append(&mut self.advance()); // |
let (maybe_rhs, mut ds) = self.bitwise_xor_expression();
let (rhs, mut ds) = self.bitwise_xor_expression();
diagnostics.append(&mut ds);
let rhs = match maybe_rhs {
Some(rhs) => rhs,
None => {
return (None, diagnostics);
}
};
let source_range =
SourceRange::new(base.source_range().start(), rhs.source_range().end());
base = Expression::Binary(BinaryExpression::new(
@ -1088,32 +1056,19 @@ impl<'a> Parser<'a> {
source_range,
));
}
(Some(base), diagnostics)
(base, diagnostics)
}
fn bitwise_xor_expression(&mut self) -> ParseResult<Option<Expression>> {
fn bitwise_xor_expression(&mut self) -> ParseResult<Expression> {
let mut diagnostics = Vec::new();
let (maybe_base, mut ds) = self.bitwise_and_expression();
let (mut base, mut ds) = self.bitwise_and_expression();
diagnostics.append(&mut ds);
let mut base = match maybe_base {
Some(base) => base,
None => {
return (None, diagnostics);
}
};
while self.current.is_some() && self.peek_current(TokenKind::Caret) {
diagnostics.append(&mut self.advance()); // ^
let (maybe_rhs, mut ds) = self.bitwise_and_expression();
let (rhs, mut ds) = self.bitwise_and_expression();
diagnostics.append(&mut ds);
let rhs = match maybe_rhs {
Some(rhs) => rhs,
None => {
return (None, diagnostics);
}
};
let source_range =
SourceRange::new(base.source_range().start(), rhs.source_range().end());
base = Expression::Binary(BinaryExpression::new(
@ -1124,31 +1079,19 @@ impl<'a> Parser<'a> {
source_range,
));
}
(Some(base), diagnostics)
(base, diagnostics)
}
fn bitwise_and_expression(&mut self) -> ParseResult<Option<Expression>> {
fn bitwise_and_expression(&mut self) -> ParseResult<Expression> {
let mut diagnostics = Vec::new();
let (maybe_base, mut ds) = self.shift_expression();
let (mut base, mut ds) = self.shift_expression();
diagnostics.append(&mut ds);
let mut base = match maybe_base {
Some(base) => base,
None => {
return (None, diagnostics);
}
};
while self.current.is_some() && self.peek_current(TokenKind::Ampersand) {
diagnostics.append(&mut self.advance()); // &
let (maybe_rhs, mut ds) = self.shift_expression();
let (rhs, mut ds) = self.shift_expression();
diagnostics.append(&mut ds);
let rhs = match maybe_rhs {
Some(rhs) => rhs,
None => {
return (None, diagnostics);
}
};
let source_range =
SourceRange::new(base.source_range().start(), rhs.source_range().end());
@ -1160,20 +1103,14 @@ impl<'a> Parser<'a> {
source_range,
));
}
(Some(base), diagnostics)
(base, diagnostics)
}
fn shift_expression(&mut self) -> ParseResult<Option<Expression>> {
fn shift_expression(&mut self) -> ParseResult<Expression> {
let mut diagnostics = Vec::new();
let (maybe_base, mut ds) = self.additive_expression();
let (mut base, mut ds) = self.additive_expression();
diagnostics.append(&mut ds);
let mut base = match maybe_base {
Some(base) => base,
None => {
return (None, diagnostics);
}
};
while self.current.is_some() {
let current = self.current.as_ref().unwrap();
@ -1185,14 +1122,8 @@ impl<'a> Parser<'a> {
self.expect_immediately_after_advance(TokenKind::Lt, &previous_cloned); // second <
diagnostics.append(&mut ds);
let (maybe_rhs, mut ds) = self.additive_expression();
let (rhs, mut ds) = self.additive_expression();
diagnostics.append(&mut ds);
let rhs = match maybe_rhs {
Some(rhs) => rhs,
None => {
return (None, diagnostics);
}
};
let source_range =
SourceRange::new(base.source_range().start(), rhs.source_range().end());
@ -1211,14 +1142,8 @@ impl<'a> Parser<'a> {
self.expect_immediately_after_advance(TokenKind::Gt, &previous_cloned); // second >
diagnostics.append(&mut ds);
let (maybe_rhs, mut ds) = self.additive_expression();
let (rhs, mut ds) = self.additive_expression();
diagnostics.append(&mut ds);
let rhs = match maybe_rhs {
Some(rhs) => rhs,
None => {
return (None, diagnostics);
}
};
let source_range =
SourceRange::new(base.source_range().start(), rhs.source_range().end());
@ -1234,34 +1159,22 @@ impl<'a> Parser<'a> {
}
}
(Some(base), diagnostics)
(base, diagnostics)
}
fn additive_expression(&mut self) -> ParseResult<Option<Expression>> {
fn additive_expression(&mut self) -> ParseResult<Expression> {
let mut diagnostics = Vec::new();
let (maybe_base, mut ds) = self.multiplicative_expression();
let (mut base, mut ds) = self.multiplicative_expression();
diagnostics.append(&mut ds);
let mut base = match maybe_base {
Some(base) => base,
None => {
return (None, diagnostics);
}
};
while self.current.is_some() {
let current = self.current.as_ref().unwrap();
match current.kind() {
TokenKind::Plus => {
diagnostics.append(&mut self.advance()); // plus
let (maybe_rhs, mut ds) = self.multiplicative_expression();
let (rhs, mut ds) = self.multiplicative_expression();
diagnostics.append(&mut ds);
let rhs = match maybe_rhs {
Some(rhs) => rhs,
None => {
return (None, diagnostics);
}
};
let source_range =
SourceRange::new(base.source_range().start(), rhs.source_range().end());
@ -1275,14 +1188,8 @@ impl<'a> Parser<'a> {
}
TokenKind::Minus => {
diagnostics.append(&mut self.advance()); // minus
let (maybe_rhs, mut ds) = self.multiplicative_expression();
let (rhs, mut ds) = self.multiplicative_expression();
diagnostics.append(&mut ds);
let rhs = match maybe_rhs {
Some(rhs) => rhs,
None => {
return (None, diagnostics);
}
};
let source_range =
SourceRange::new(base.source_range().start(), rhs.source_range().end());
@ -1297,34 +1204,22 @@ impl<'a> Parser<'a> {
_ => break,
}
}
(Some(base), diagnostics)
(base, diagnostics)
}
fn multiplicative_expression(&mut self) -> ParseResult<Option<Expression>> {
fn multiplicative_expression(&mut self) -> ParseResult<Expression> {
let mut diagnostics = Vec::new();
let (maybe_base, mut ds) = self.prefix_expression();
let (mut base, mut ds) = self.prefix_expression();
diagnostics.append(&mut ds);
let mut base = match maybe_base {
Some(base) => base,
None => {
return (None, diagnostics);
}
};
while self.current.is_some() {
let current = self.current.as_ref().unwrap();
match current.kind() {
TokenKind::Star => {
diagnostics.append(&mut self.advance()); // multiply
let (maybe_rhs, mut ds) = self.prefix_expression();
let (rhs, mut ds) = self.prefix_expression();
diagnostics.append(&mut ds);
let rhs = match maybe_rhs {
Some(rhs) => rhs,
None => {
return (None, diagnostics);
}
};
let source_range =
SourceRange::new(base.source_range().start(), rhs.source_range().end());
@ -1338,14 +1233,8 @@ impl<'a> Parser<'a> {
}
TokenKind::Slash => {
diagnostics.append(&mut self.advance()); // slash
let (maybe_rhs, mut ds) = self.prefix_expression();
let (rhs, mut ds) = self.prefix_expression();
diagnostics.append(&mut ds);
let rhs = match maybe_rhs {
Some(rhs) => rhs,
None => {
return (None, diagnostics);
}
};
let source_range =
SourceRange::new(base.source_range().start(), rhs.source_range().end());
@ -1359,14 +1248,8 @@ impl<'a> Parser<'a> {
}
TokenKind::Modulo => {
diagnostics.append(&mut self.advance()); // modulo
let (maybe_rhs, mut ds) = self.prefix_expression();
let (rhs, mut ds) = self.prefix_expression();
diagnostics.append(&mut ds);
let rhs = match maybe_rhs {
Some(rhs) => rhs,
None => {
return (None, diagnostics);
}
};
let source_range =
SourceRange::new(base.source_range().start(), rhs.source_range().end());
@ -1381,10 +1264,10 @@ impl<'a> Parser<'a> {
_ => break,
}
}
(Some(base), diagnostics)
(base, diagnostics)
}
fn prefix_expression(&mut self) -> ParseResult<Option<Expression>> {
fn prefix_expression(&mut self) -> ParseResult<Expression> {
let mut diagnostics = Vec::new();
// first, collect all consecutive operators
@ -1403,14 +1286,8 @@ impl<'a> Parser<'a> {
// now go in reverse and build up expressions
// the parser is currently just after the prefix operators, so we need a suffix expression
// as a base
let (maybe_base, mut ds) = self.suffix_expression();
let (mut base, mut ds) = self.suffix_expression();
diagnostics.append(&mut ds);
let mut base = match maybe_base {
Some(base) => base,
None => {
return (None, diagnostics);
}
};
while let Some(operator_token) = operator_tokens.pop() {
let source_range = SourceRange::new(operator_token.start(), base.source_range().end());
@ -1425,20 +1302,14 @@ impl<'a> Parser<'a> {
_ => unreachable!(),
}
}
(Some(base), diagnostics)
(base, diagnostics)
}
fn suffix_expression(&mut self) -> ParseResult<Option<Expression>> {
fn suffix_expression(&mut self) -> ParseResult<Expression> {
let mut diagnostics = Vec::new();
let (maybe_base, mut ds) = self.expression_base();
let (mut base, mut ds) = self.expression_base();
diagnostics.append(&mut ds);
let mut base = match maybe_base {
Some(base) => base,
None => {
return (None, diagnostics);
}
};
while self.current.is_some() {
let current = self.current.as_ref().unwrap();
@ -1452,10 +1323,10 @@ impl<'a> Parser<'a> {
}
}
(Some(base), diagnostics)
(base, diagnostics)
}
fn expression_base(&mut self) -> ParseResult<Option<Expression>> {
fn expression_base(&mut self) -> ParseResult<Expression> {
let current = match self.current.as_ref() {
None => {
let mut ds = Diagnostics::new();
@ -1463,7 +1334,7 @@ impl<'a> Parser<'a> {
&EXPRESSION_FIRSTS,
self.input.len(),
));
return (None, ds);
return (todo!(), ds);
}
Some(current) => current,
};
@ -1474,11 +1345,11 @@ impl<'a> Parser<'a> {
let source_range = SourceRange::new(current.start(), current.end());
diagnostics.append(&mut self.advance());
(
Some(Expression::Integer(IntegerLiteral::new(
Expression::Integer(IntegerLiteral::new(
self.next_node_id(),
i32::from_str(raw).unwrap(),
source_range,
))),
)),
diagnostics,
)
}
@ -1487,11 +1358,11 @@ impl<'a> Parser<'a> {
let source_range = SourceRange::new(current.start(), current.end());
diagnostics.append(&mut self.advance());
(
Some(Expression::Double(DoubleLiteral::new(
Expression::Double(DoubleLiteral::new(
self.next_node_id(),
f64::from_str(raw).unwrap(),
source_range,
))),
)),
diagnostics,
)
}
@ -1500,11 +1371,11 @@ impl<'a> Parser<'a> {
let source_range = SourceRange::new(current.start(), current.end());
diagnostics.append(&mut self.advance());
(
Some(Expression::String(StringLiteral::new(
Expression::String(StringLiteral::new(
self.next_node_id(),
&with_quotes[1..with_quotes.len() - 1],
source_range,
))),
)),
diagnostics,
)
}
@ -1513,11 +1384,11 @@ impl<'a> Parser<'a> {
let source_range = SourceRange::new(current.start(), current.end());
diagnostics.append(&mut self.advance());
(
Some(Expression::Identifier(Identifier::new(
Expression::Identifier(Identifier::new(
self.next_node_id(),
declared_name,
source_range,
))),
)),
diagnostics,
)
}
@ -1559,18 +1430,14 @@ impl<'a> Parser<'a> {
let mut expressions = vec![];
let mut diagnostics = Vec::new();
let (maybe_expression, mut ds) = self.expression();
if let Some(expression) = maybe_expression {
expressions.push(expression);
}
let (expression, mut ds) = self.expression();
expressions.push(expression);
diagnostics.append(&mut ds);
while self.current.is_some() && self.peek_current(TokenKind::Comma) {
diagnostics.append(&mut self.advance()); // comma
let (maybe_expression, mut ds) = self.expression();
if let Some(expression) = maybe_expression {
expressions.push(expression);
}
let (expression, mut ds) = self.expression();
expressions.push(expression);
diagnostics.append(&mut ds);
}
@ -1810,15 +1677,11 @@ mod concrete_tests {
}
fn assert_expression(input: &str) -> Expression {
let (maybe_expression, diagnostics) = parse_expression(input);
let (expression, diagnostics) = parse_expression(input);
if !diagnostics.is_empty() {
report_diagnostics(&diagnostics);
}
if let Some(expression) = maybe_expression {
expression
} else {
panic!("parse_expression produced a None")
}
expression
}
fn assert_function_in<'a>(