add Ascend/Descend nodes to AST,Parser&Lexer
This commit is contained in:
parent
08f592ad60
commit
7cc47f05c5
5 changed files with 93 additions and 6 deletions
|
@ -54,6 +54,14 @@ pub enum LTExpr {
|
||||||
typ: Option<TypeTag>,
|
typ: Option<TypeTag>,
|
||||||
symbol: String,
|
symbol: String,
|
||||||
},
|
},
|
||||||
|
Ascend {
|
||||||
|
typ: TypeTag,
|
||||||
|
expr: Box<LTExpr>
|
||||||
|
},
|
||||||
|
Descend {
|
||||||
|
typ: TypeTag,
|
||||||
|
expr: Box<LTExpr>
|
||||||
|
},
|
||||||
Application {
|
Application {
|
||||||
typ: Option<TypeTag>,
|
typ: Option<TypeTag>,
|
||||||
head: Box<LTExpr>,
|
head: Box<LTExpr>,
|
||||||
|
|
|
@ -16,6 +16,9 @@ pub enum LTIRToken {
|
||||||
ExprOpen,
|
ExprOpen,
|
||||||
ExprClose,
|
ExprClose,
|
||||||
|
|
||||||
|
Ascend(String),
|
||||||
|
Descend(String),
|
||||||
|
|
||||||
BlockOpen,
|
BlockOpen,
|
||||||
BlockClose,
|
BlockClose,
|
||||||
StatementSep,
|
StatementSep,
|
||||||
|
@ -36,7 +39,10 @@ pub enum LexerState {
|
||||||
Sym(String),
|
Sym(String),
|
||||||
Num(i64),
|
Num(i64),
|
||||||
Char(Option<char>),
|
Char(Option<char>),
|
||||||
DoubleQuote(String)
|
DoubleQuote(String),
|
||||||
|
|
||||||
|
Ascend(String),
|
||||||
|
Descend(String)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LexerState {
|
impl LexerState {
|
||||||
|
@ -48,7 +54,9 @@ impl LexerState {
|
||||||
LexerState::Sym(s) => Some(LTIRToken::Symbol(s)),
|
LexerState::Sym(s) => Some(LTIRToken::Symbol(s)),
|
||||||
LexerState::Num(n) => Some(LTIRToken::Num(n)),
|
LexerState::Num(n) => Some(LTIRToken::Num(n)),
|
||||||
LexerState::Char(c) => Some(LTIRToken::Char(c?)),
|
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()
|
if c.is_whitespace()
|
||||||
|| *c == '('
|
|| *c == '('
|
||||||
|
@ -341,6 +362,24 @@ where
|
||||||
|| *c == '↦'
|
|| *c == '↦'
|
||||||
{
|
{
|
||||||
// finish the current token
|
// 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() {
|
if let Some(token) = state.clone().into_token() {
|
||||||
return Some((region, Ok(token)));
|
return Some((region, Ok(token)));
|
||||||
|
|
|
@ -351,6 +351,40 @@ where It: Iterator<Item = (InputRegionTag, Result<LTIRToken, LexError>)>
|
||||||
tokens.next();
|
tokens.next();
|
||||||
children.push(LTExpr::StringLiteral{ region, value });
|
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() {
|
Ok(LTIRToken::Symbol(name)) => match name.as_str() {
|
||||||
"if" => {
|
"if" => {
|
||||||
tokens.next();
|
tokens.next();
|
||||||
|
|
|
@ -234,6 +234,12 @@ impl ProcedureCompiler {
|
||||||
LTExpr::WordLiteral { typ, val } => {
|
LTExpr::WordLiteral { typ, val } => {
|
||||||
self.asm = self.asm.lit(*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 } => {
|
LTExpr::Application { typ, head, body } => {
|
||||||
for arg in body.iter().rev() {
|
for arg in body.iter().rev() {
|
||||||
self = self.compile(arg);
|
self = self.compile(arg);
|
||||||
|
|
|
@ -25,11 +25,11 @@ export {
|
||||||
{bp:ℕ; bq:ℕ;}: ℚ ~ <Ratio ℕ ~ ℤ_2^64 ~ machine.UInt64> ;
|
{bp:ℕ; bq:ℕ;}: ℚ ~ <Ratio ℕ ~ ℤ_2^64 ~ machine.UInt64> ;
|
||||||
} ↦ {
|
} ↦ {
|
||||||
let l = lcm aq bq;
|
let l = lcm aq bq;
|
||||||
let as = i/ l aq;
|
let a = i/ l aq;
|
||||||
let bs = i/ l bq;
|
let b = i/ l bq;
|
||||||
|
|
||||||
i* aq as;
|
i* aq a;
|
||||||
i+ (i* ap as) (i* bp bs);
|
i+ (i* ap a) (i* bp b);
|
||||||
};
|
};
|
||||||
|
|
||||||
let ratio-mul = λ{
|
let ratio-mul = λ{
|
||||||
|
|
Loading…
Reference in a new issue