feat: add constant and delay parsing
This commit is contained in:
parent
501396450f
commit
6c31acbf5d
|
@ -1,3 +1,3 @@
|
|||
(program 1.0.0
|
||||
[[(builtin addInteger) (con integer 4)] (con integer 8)]
|
||||
(con integer 4)
|
||||
)
|
22
src/ast.rs
22
src/ast.rs
|
@ -1,36 +1,36 @@
|
|||
#[derive(Debug)]
|
||||
pub struct Program<'a> {
|
||||
pub struct Program {
|
||||
pub version: String,
|
||||
pub term: Term<'a>,
|
||||
pub term: Term,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Term<'a> {
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Term {
|
||||
// tag: 0
|
||||
Var(String),
|
||||
// tag: 1
|
||||
Delay(&'a Term<'a>),
|
||||
Delay(Box<Term>),
|
||||
// tag: 2
|
||||
Lambda {
|
||||
parameter_name: String,
|
||||
body: &'a Term<'a>,
|
||||
body: Box<Term>,
|
||||
},
|
||||
// tag: 3
|
||||
Apply {
|
||||
function: &'a Term<'a>,
|
||||
argument: &'a Term<'a>,
|
||||
function: Box<Term>,
|
||||
argument: Box<Term>,
|
||||
},
|
||||
// tag: 4
|
||||
Constant(Constant),
|
||||
// tag: 5
|
||||
Force(&'a Term<'a>),
|
||||
Force(Box<Term>),
|
||||
// tag: 6
|
||||
Error(&'a Term<'a>),
|
||||
Error(Box<Term>),
|
||||
// tag: 7
|
||||
// Builtin
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Constant {
|
||||
// TODO: figure out the right size for this
|
||||
// tag: 0
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use combine::{
|
||||
between,
|
||||
between, many1,
|
||||
parser::char::{digit, spaces, string},
|
||||
sep_by, token, ParseError, Parser, Stream,
|
||||
token, ParseError, Parser, Stream,
|
||||
};
|
||||
|
||||
use crate::ast::{Program, Term};
|
||||
use crate::ast::{Constant, Program, Term};
|
||||
|
||||
pub fn program(src: &str) -> anyhow::Result<Program> {
|
||||
let mut parser = program_();
|
||||
|
@ -16,7 +16,7 @@ pub fn program(src: &str) -> anyhow::Result<Program> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn program_<'a, Input>() -> impl Parser<Input, Output = Program<'a>>
|
||||
pub fn program_<Input>() -> impl Parser<Input, Output = Program>
|
||||
where
|
||||
Input: Stream<Token = char>,
|
||||
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
|
||||
|
@ -33,15 +33,81 @@ where
|
|||
Input: Stream<Token = char>,
|
||||
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
|
||||
{
|
||||
sep_by(digit(), token('.'))
|
||||
(
|
||||
many1(digit()),
|
||||
token('.'),
|
||||
many1(digit()),
|
||||
token('.'),
|
||||
many1(digit()),
|
||||
)
|
||||
.map(
|
||||
|(major, _, minor, _, patch): (String, char, String, char, String)| {
|
||||
format!("{}.{}.{}", major, minor, patch)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn term<'a, Input>() -> impl Parser<Input, Output = Term<'a>>
|
||||
pub fn term<Input>() -> impl Parser<Input, Output = Term>
|
||||
where
|
||||
Input: Stream<Token = char>,
|
||||
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
|
||||
{
|
||||
string("var").map(|x| Term::Var(x.to_string()))
|
||||
between(token('('), token(')'), constant()).skip(spaces())
|
||||
}
|
||||
|
||||
pub fn delay<Input>() -> impl Parser<Input, Output = Term>
|
||||
where
|
||||
Input: Stream<Token = char>,
|
||||
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
|
||||
{
|
||||
string("delay")
|
||||
.skip(spaces())
|
||||
.with(term())
|
||||
.map(|term| Term::Delay(Box::new(term)))
|
||||
}
|
||||
|
||||
pub fn constant<Input>() -> impl Parser<Input, Output = Term>
|
||||
where
|
||||
Input: Stream<Token = char>,
|
||||
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
|
||||
{
|
||||
string("con")
|
||||
.skip(spaces())
|
||||
.with(constant_integer().or(unit()).or(constant_bool()))
|
||||
.map(Term::Constant)
|
||||
}
|
||||
|
||||
pub fn constant_integer<Input>() -> impl Parser<Input, Output = Constant>
|
||||
where
|
||||
Input: Stream<Token = char>,
|
||||
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
|
||||
{
|
||||
string("integer")
|
||||
.skip(spaces())
|
||||
.with(many1(digit()))
|
||||
.map(|d: String| Constant::Integer(d.parse::<i64>().unwrap()))
|
||||
}
|
||||
|
||||
pub fn constant_bool<Input>() -> impl Parser<Input, Output = Constant>
|
||||
where
|
||||
Input: Stream<Token = char>,
|
||||
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
|
||||
{
|
||||
string("bool")
|
||||
.skip(spaces())
|
||||
.with(string("True").or(string("False")))
|
||||
.map(|b| Constant::Bool(b == "True"))
|
||||
}
|
||||
|
||||
pub fn unit<Input>() -> impl Parser<Input, Output = Constant>
|
||||
where
|
||||
Input: Stream<Token = char>,
|
||||
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
|
||||
{
|
||||
string("unit")
|
||||
.skip(spaces())
|
||||
.with(string("()"))
|
||||
.map(|_| Constant::Unit)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
Loading…
Reference in New Issue