[fine] OK
This commit is contained in:
parent
50eb7a9673
commit
65fef78c44
10 changed files with 81 additions and 25 deletions
|
|
@ -20,7 +20,7 @@ fn generate_test_for_file(path: PathBuf) -> String {
|
||||||
};
|
};
|
||||||
|
|
||||||
let line = line.trim();
|
let line = line.trim();
|
||||||
if line == "@disabled" {
|
if line == "@ignore" {
|
||||||
disabled = quote! { #[ignore] };
|
disabled = quote! { #[ignore] };
|
||||||
} else if line == "@concrete:" {
|
} else if line == "@concrete:" {
|
||||||
let mut concrete = String::new();
|
let mut concrete = String::new();
|
||||||
|
|
@ -78,6 +78,10 @@ fn generate_test_for_file(path: PathBuf) -> String {
|
||||||
assertions.push(quote! {
|
assertions.push(quote! {
|
||||||
crate::assert_type_error_at(&_tree, &_lines, #pos, #expected, #display_path);
|
crate::assert_type_error_at(&_tree, &_lines, #pos, #expected, #display_path);
|
||||||
});
|
});
|
||||||
|
} else if line == "@no-errors" {
|
||||||
|
assertions.push(quote! {
|
||||||
|
crate::assert_no_errors(&_tree, &_lines);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -219,10 +219,15 @@ pub fn compile(semantics: &Semantics) -> Module {
|
||||||
fn file(c: &mut Compiler, t: TreeRef) {
|
fn file(c: &mut Compiler, t: TreeRef) {
|
||||||
let tree = &c.syntax[t];
|
let tree = &c.syntax[t];
|
||||||
compiler_assert_eq!(c, t, tree.kind, TreeKind::File, "must be compiling a file");
|
compiler_assert_eq!(c, t, tree.kind, TreeKind::File, "must be compiling a file");
|
||||||
for i in 0..tree.children.len() {
|
|
||||||
if let Some(t) = tree.nth_tree(i) {
|
let children: Vec<_> = tree.child_trees().collect();
|
||||||
compile_statement(c, t, false);
|
if children.len() == 0 {
|
||||||
|
c.push(Instruction::PushNothing);
|
||||||
|
} else {
|
||||||
|
for i in 0..children.len() - 1 {
|
||||||
|
compile_statement(c, children[i], false);
|
||||||
}
|
}
|
||||||
|
compile_statement(c, *children.last().unwrap(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -485,18 +490,23 @@ fn compile_if_statement(c: &mut Compiler, tree: &Tree, gen_value: bool) -> CR {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_expression_statement(c: &mut Compiler, tree: &Tree, gen_value: bool) -> CR {
|
fn compile_expression_statement(c: &mut Compiler, tree: &Tree, gen_value: bool) -> CR {
|
||||||
compile_expression(c, tree.nth_tree(0)?);
|
if let Some(expr) = tree.nth_tree(0) {
|
||||||
if tree
|
compile_expression(c, expr);
|
||||||
.nth_token(1)
|
|
||||||
.is_some_and(|t| t.kind == TokenKind::Semicolon)
|
if tree
|
||||||
{
|
.nth_token(1)
|
||||||
c.push(Instruction::Discard);
|
.is_some_and(|t| t.kind == TokenKind::Semicolon)
|
||||||
if gen_value {
|
{
|
||||||
c.push(Instruction::PushNothing);
|
c.push(Instruction::Discard);
|
||||||
|
if gen_value {
|
||||||
|
c.push(Instruction::PushNothing);
|
||||||
|
}
|
||||||
|
} else if !gen_value {
|
||||||
|
c.push(Instruction::Discard);
|
||||||
}
|
}
|
||||||
} else if !gen_value {
|
} else if gen_value {
|
||||||
c.push(Instruction::Discard);
|
c.push(Instruction::PushNothing);
|
||||||
}
|
};
|
||||||
|
|
||||||
OK
|
OK
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -641,7 +641,9 @@ fn statement_return(p: &mut CParser) {
|
||||||
fn statement_expression(p: &mut CParser) {
|
fn statement_expression(p: &mut CParser) {
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
|
|
||||||
expression(p);
|
if !p.at(TokenKind::RightBrace) && !p.at(TokenKind::Semicolon) {
|
||||||
|
expression(p);
|
||||||
|
}
|
||||||
if !p.at(TokenKind::RightBrace) {
|
if !p.at(TokenKind::RightBrace) {
|
||||||
p.expect(
|
p.expect(
|
||||||
TokenKind::Semicolon,
|
TokenKind::Semicolon,
|
||||||
|
|
|
||||||
|
|
@ -929,6 +929,18 @@ impl<'a> Semantics<'a> {
|
||||||
|
|
||||||
Some(*ret.clone())
|
Some(*ret.clone())
|
||||||
}
|
}
|
||||||
|
Type::MagicPrintGarbage => {
|
||||||
|
if arg_types.len() > 1 {
|
||||||
|
self.report_error_tree(tree, "print takes a single argument");
|
||||||
|
Some(Type::Error)
|
||||||
|
} else if arg_types.len() == 0 {
|
||||||
|
Some(Type::Nothing)
|
||||||
|
} else {
|
||||||
|
let mut arg_types = arg_types;
|
||||||
|
let (_, t) = arg_types.pop().unwrap();
|
||||||
|
Some(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.report_error_tree_ref(f_ref, format!("expected a function type, got: {f}"));
|
self.report_error_tree_ref(f_ref, format!("expected a function type, got: {f}"));
|
||||||
Some(Type::Error)
|
Some(Type::Error)
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ e.g., a test might look like this:
|
||||||
|
|
||||||
The various assertions are as follows:
|
The various assertions are as follows:
|
||||||
|
|
||||||
- The `// @disabled` directive marks the test as ignored.
|
- The `// @ignore` directive marks the test as ignored.
|
||||||
|
|
||||||
- The `// @concrete:` assertion says that the following lines
|
- The `// @concrete:` assertion says that the following lines
|
||||||
(prefixed with `// | `, as above) describe the concrete syntax tree
|
(prefixed with `// | `, as above) describe the concrete syntax tree
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use fine::compiler::{compile, Function, Module};
|
use fine::compiler::{compile, Function, Module};
|
||||||
use fine::parser::SyntaxTree;
|
use fine::parser::SyntaxTree;
|
||||||
use fine::semantics::{Semantics, Type};
|
use fine::semantics::{check, Error, Semantics, Type};
|
||||||
use fine::tokens::Lines;
|
use fine::tokens::Lines;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use std::fmt::Write as _;
|
use std::fmt::Write as _;
|
||||||
|
|
@ -243,4 +243,19 @@ fn assert_compiles_to(tree: &SyntaxTree, lines: &Lines, expected: &str, source_p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn assert_no_errors(tree: &SyntaxTree, lines: &Lines) {
|
||||||
|
let semantics = Semantics::new(tree, lines);
|
||||||
|
check(&semantics);
|
||||||
|
|
||||||
|
let expected_errors: Vec<Error> = Vec::new();
|
||||||
|
let errors = semantics.snapshot_errors();
|
||||||
|
semantic_assert_eq!(
|
||||||
|
&semantics,
|
||||||
|
None,
|
||||||
|
expected_errors,
|
||||||
|
errors,
|
||||||
|
"expected no errors"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/generated_tests.rs"));
|
include!(concat!(env!("OUT_DIR"), "/generated_tests.rs"));
|
||||||
|
|
|
||||||
|
|
@ -36,5 +36,6 @@ fun foo(x: f64) {
|
||||||
// | 2: FloatAdd
|
// | 2: FloatAdd
|
||||||
// | function << module >> (0 args, 0 locals):
|
// | function << module >> (0 args, 0 locals):
|
||||||
// | strings (0):
|
// | strings (0):
|
||||||
// | code (0):
|
// | code (1):
|
||||||
|
// | 0: PushNothing
|
||||||
// |
|
// |
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
// @compiles-to:
|
// @compiles-to:
|
||||||
// | function << module >> (0 args, 0 locals):
|
// | function << module >> (0 args, 0 locals):
|
||||||
// | strings (0):
|
// | strings (0):
|
||||||
// | code (10):
|
// | code (11):
|
||||||
// | 0: PushFloat(1.0)
|
// | 0: PushFloat(1.0)
|
||||||
// | 1: PushFloat(2.0)
|
// | 1: PushFloat(2.0)
|
||||||
// | 2: FloatMultiply
|
// | 2: FloatMultiply
|
||||||
|
|
@ -36,4 +36,5 @@
|
||||||
// | 7: FloatMultiply
|
// | 7: FloatMultiply
|
||||||
// | 8: FloatAdd
|
// | 8: FloatAdd
|
||||||
// | 9: Discard
|
// | 9: Discard
|
||||||
|
// | 10: PushNothing
|
||||||
// |
|
// |
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,14 @@
|
||||||
// @disabled
|
|
||||||
// @concrete:
|
|
||||||
// |
|
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
// @no-errors
|
||||||
|
// @concrete:
|
||||||
|
// | File
|
||||||
|
// | ExpressionStatement
|
||||||
|
// | Semicolon:'";"'
|
||||||
|
// |
|
||||||
|
// @compiles-to:
|
||||||
|
// | function << module >> (0 args, 0 locals):
|
||||||
|
// | strings (0):
|
||||||
|
// | code (1):
|
||||||
|
// | 0: PushNothing
|
||||||
|
// |
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ let y = x * 2;
|
||||||
let z = print(y);
|
let z = print(y);
|
||||||
z;
|
z;
|
||||||
|
|
||||||
|
// @no-errors
|
||||||
// @type: 41 f64
|
// @type: 41 f64
|
||||||
// @concrete:
|
// @concrete:
|
||||||
// | File
|
// | File
|
||||||
|
|
@ -46,7 +47,7 @@ z;
|
||||||
// @compiles-to:
|
// @compiles-to:
|
||||||
// | function << module >> (0 args, 0 locals):
|
// | function << module >> (0 args, 0 locals):
|
||||||
// | strings (0):
|
// | strings (0):
|
||||||
// | code (12):
|
// | code (13):
|
||||||
// | 0: PushFloat(23.0)
|
// | 0: PushFloat(23.0)
|
||||||
// | 1: StoreModule(0)
|
// | 1: StoreModule(0)
|
||||||
// | 2: LoadModule(0)
|
// | 2: LoadModule(0)
|
||||||
|
|
@ -59,4 +60,5 @@ z;
|
||||||
// | 9: StoreModule(2)
|
// | 9: StoreModule(2)
|
||||||
// | 10: LoadModule(2)
|
// | 10: LoadModule(2)
|
||||||
// | 11: Discard
|
// | 11: Discard
|
||||||
|
// | 12: PushNothing
|
||||||
// |
|
// |
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue