Skip to content

Commit

Permalink
Show that we can 'safely' mutate the context (though only children of…
Browse files Browse the repository at this point in the history
… the root should be trusted as back tracking may be supported
  • Loading branch information
Cypher1 committed Sep 28, 2024
1 parent 5552620 commit c90f00b
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
8 changes: 6 additions & 2 deletions takolib/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,14 @@ pub fn parse(_file: &Path, _s: &str, _tokens: &[Token]) -> Result<Ast, TError> {
#[test]
fn simple_expressions() {
// Get the `LexerDef` for the `tako` language.
let path = Path::new("test.tk").to_path_buf();
let mut ast = Ast::new(path);
let lexerdef = tako_l::lexerdef();
let mut results = vec![];
let input = "2 + 3
2 + 3 * 4
(2 + 3) * 4
[2 3 4]
";
for l in input.lines() {
println!(">>> {l}");
Expand All @@ -244,7 +247,7 @@ fn simple_expressions() {
// we can lex an input.
let lexer = lexerdef.lexer(l);
// Pass the lexer to the parser and lex and parse the input.
let (res, errs) = tako_y::parse(&lexer);
let (res, errs) = tako_y::parse(&lexer, &mut ast);
for e in errs {
println!("{}", e.pp(&lexer, &tako_y::token_epp));
}
Expand All @@ -259,5 +262,6 @@ fn simple_expressions() {
None => eprintln!("Unable to evaluate expression."),
}
}
assert_eq!(results, [Ok(5), Ok(14), Ok(20)]);
assert_eq!(results, [Ok(5), Ok(14), Ok(20), Ok(3)]);
assert_eq!(ast.ops.len(), 3);
}
43 changes: 42 additions & 1 deletion takolib/src/tako.y
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
%start Expr
%parse-param ctx: *mut crate::parser::Ast
%%
Expr -> Result<u64, ()>:
Expr 'Add' Term { Ok($1? + $3?) }
Expr 'Add' Term {
with(ctx).add_op(Op{ op: Symbol::Add, args: smallvec![] }, Location { start: 0, length: 0});
Ok($1? + $3?)
}
| 'OpenBracket' ManyTerms 'CloseBracket' { Ok( $2?.len() as u64) }
| Term { $1 }
;

Expand All @@ -19,9 +24,36 @@ Factor -> Result<u64, ()>:
}
;

ManyTerms -> Result<Vec<u64>, ()>:
Term { Ok(vec![$1?]) }
| ManyTerms Term { flatten($1, $2) }
;

%%

use smallvec::smallvec;
use crate::ast::*;
use crate::parser::{Symbol, Location};
// Any functions here are in scope for all the grammar actions above.

fn with(ctx: *mut crate::parser::Ast) -> &'static mut Ast {
// TODO: Replace with this something safer... but... for now
// the context is guaranteed to live long enough and not be moved.
unsafe {&mut (*ctx)}
}

//AssignExpr -> ASTAssign: 'Assign' Expr
//{
// let v = $2?;
//ASTAssign { $1.span(), expr: Box.new(v) }
//};

// | AssignExpr { Ok( 0 ) }
// struct ASTAssign {
// id: lrpar::Span,
// expr: Box<u32>,
// }

fn parse_int(s: &str) -> Result<u64, ()> {
match s.parse::<u64>() {
Ok(val) => Ok(val),
Expand All @@ -32,6 +64,15 @@ fn parse_int(s: &str) -> Result<u64, ()> {
}
}

fn flatten<T>(lhs: Result<Vec<T>, ()>, rhs: Result<T, ()>)
-> Result<Vec<T>, ()>
{
let mut flt = lhs?;
flt.push(rhs?);
Ok(flt)
}


/*
RIGHT_ASSOCIATIVE
Symbol::Exp,
Expand Down

0 comments on commit c90f00b

Please sign in to comment.