[fine] OK

This commit is contained in:
John Doty 2024-01-13 15:07:38 -08:00
parent 50eb7a9673
commit 65fef78c44
10 changed files with 81 additions and 25 deletions

View file

@ -219,10 +219,15 @@ pub fn compile(semantics: &Semantics) -> Module {
fn file(c: &mut Compiler, t: TreeRef) {
let tree = &c.syntax[t];
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) {
compile_statement(c, t, false);
let children: Vec<_> = tree.child_trees().collect();
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 {
compile_expression(c, tree.nth_tree(0)?);
if tree
.nth_token(1)
.is_some_and(|t| t.kind == TokenKind::Semicolon)
{
c.push(Instruction::Discard);
if gen_value {
c.push(Instruction::PushNothing);
if let Some(expr) = tree.nth_tree(0) {
compile_expression(c, expr);
if tree
.nth_token(1)
.is_some_and(|t| t.kind == TokenKind::Semicolon)
{
c.push(Instruction::Discard);
if gen_value {
c.push(Instruction::PushNothing);
}
} else if !gen_value {
c.push(Instruction::Discard);
}
} else if !gen_value {
c.push(Instruction::Discard);
}
} else if gen_value {
c.push(Instruction::PushNothing);
};
OK
}

View file

@ -641,7 +641,9 @@ fn statement_return(p: &mut CParser) {
fn statement_expression(p: &mut CParser) {
let m = p.start();
expression(p);
if !p.at(TokenKind::RightBrace) && !p.at(TokenKind::Semicolon) {
expression(p);
}
if !p.at(TokenKind::RightBrace) {
p.expect(
TokenKind::Semicolon,

View file

@ -929,6 +929,18 @@ impl<'a> Semantics<'a> {
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}"));
Some(Type::Error)