add Ascend/Descend nodes to AST,Parser&Lexer

This commit is contained in:
Michael Sippel 2024-09-30 11:27:35 +02:00
parent 08f592ad60
commit 7cc47f05c5
Signed by: senvas
GPG key ID: F96CF119C34B64A6
5 changed files with 93 additions and 6 deletions

View file

@ -54,6 +54,14 @@ pub enum LTExpr {
typ: Option<TypeTag>,
symbol: String,
},
Ascend {
typ: TypeTag,
expr: Box<LTExpr>
},
Descend {
typ: TypeTag,
expr: Box<LTExpr>
},
Application {
typ: Option<TypeTag>,
head: Box<LTExpr>,

View file

@ -16,6 +16,9 @@ pub enum LTIRToken {
ExprOpen,
ExprClose,
Ascend(String),
Descend(String),
BlockOpen,
BlockClose,
StatementSep,
@ -36,7 +39,10 @@ pub enum LexerState {
Sym(String),
Num(i64),
Char(Option<char>),
DoubleQuote(String)
DoubleQuote(String),
Ascend(String),
Descend(String)
}
impl LexerState {
@ -48,7 +54,9 @@ impl LexerState {
LexerState::Sym(s) => Some(LTIRToken::Symbol(s)),
LexerState::Num(n) => Some(LTIRToken::Num(n)),
LexerState::Char(c) => Some(LTIRToken::Char(c?)),
LexerState::DoubleQuote(s) => Some(LTIRToken::DoubleQuote(s))
LexerState::DoubleQuote(s) => Some(LTIRToken::DoubleQuote(s)),
LexerState::Ascend(s) => Some(LTIRToken::Ascend(s)),
LexerState::Descend(s) => Some(LTIRToken::Descend(s))
}
}
}
@ -329,6 +337,19 @@ where
}
}
LexerState::Ascend(s) |
LexerState::Descend(s) => {
if *c == ')' {
let token = state.clone().into_token().unwrap();
return Some((region, Ok(token)));
} else {
if let Some(c) = self.chars.next() {
self.position += 1;
region.end += 1;
s.push(c);
}
}
}
_ => {
if c.is_whitespace()
|| *c == '('
@ -341,6 +362,24 @@ where
|| *c == '↦'
{
// finish the current token
match &mut state {
LexerState::Sym(s) => {
match s.as_str(){
"as"=> {
self.chars.next();
state = LexerState::Ascend(String::new());
continue;
}
"des" => {
self.chars.next();
state = LexerState::Descend(String::new());
continue;
}
_ =>{}
}
}
_ => {}
}
if let Some(token) = state.clone().into_token() {
return Some((region, Ok(token)));

View file

@ -351,6 +351,40 @@ where It: Iterator<Item = (InputRegionTag, Result<LTIRToken, LexError>)>
tokens.next();
children.push(LTExpr::StringLiteral{ region, value });
}
Ok(LTIRToken::Ascend(type_str)) => {
let region = region.clone();
let typ =
match typectx.write().unwrap().parse(type_str) {
Ok(t) => Ok(t),
Err(e) => Err(TypeError::ParseError(e))
};
if let Some(expr) = children.pop() {
children.push(LTExpr::Ascend {
typ,
expr: Box::new(expr)
});
}
tokens.next();
}
Ok(LTIRToken::Descend(type_str)) => {
let region = region.clone();
let typ =
match typectx.write().unwrap().parse(type_str) {
Ok(t) => Ok(t),
Err(e) => Err(TypeError::ParseError(e))
};
if let Some(expr) = children.pop() {
children.push(LTExpr::Descend {
typ,
expr: Box::new(expr)
});
}
tokens.next();
}
Ok(LTIRToken::Symbol(name)) => match name.as_str() {
"if" => {
tokens.next();

View file

@ -234,6 +234,12 @@ impl ProcedureCompiler {
LTExpr::WordLiteral { typ, val } => {
self.asm = self.asm.lit(*val);
}
LTExpr::Ascend { typ, expr } => {
self = self.compile(expr);
}
LTExpr::Descend { typ, expr } => {
self = self.compile(expr);
}
LTExpr::Application { typ, head, body } => {
for arg in body.iter().rev() {
self = self.compile(arg);

View file

@ -25,11 +25,11 @@ export {
{bp:; bq:;}: ~ <Ratio ~ _2^64 ~ machine.UInt64> ;
} ↦ {
let l = lcm aq bq;
let as = i/ l aq;
let bs = i/ l bq;
let a = i/ l aq;
let b = i/ l bq;
i* aq as;
i+ (i* ap as) (i* bp bs);
i* aq a;
i+ (i* ap a) (i* bp b);
};
let ratio-mul = λ{