expr: replace old builder functions with direct constructors; add more region tags
This commit is contained in:
parent
1a152670d3
commit
2ac69a7b12
3 changed files with 38 additions and 36 deletions
|
@ -16,6 +16,7 @@ pub enum Statement {
|
|||
val_expr: LTExpr,
|
||||
},
|
||||
LetAssign {
|
||||
name_region: InputRegionTag,
|
||||
typ: Option<TypeTag>,
|
||||
var_id: String,
|
||||
val_expr: LTExpr,
|
||||
|
@ -109,34 +110,5 @@ impl LTExpr {
|
|||
LTExpr::ExportBlock{ region, statements } => region
|
||||
}.clone()
|
||||
}
|
||||
|
||||
pub fn lit_uint(val: u64) -> Self {
|
||||
LTExpr::WordLiteral {
|
||||
region: InputRegionTag::default(),
|
||||
val: val as tisc::VM_Word,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn application(head: LTExpr, body: Vec<LTExpr>) -> Self {
|
||||
LTExpr::Application {
|
||||
region: InputRegionTag::default(),
|
||||
typ: None,
|
||||
head: Box::new(head),
|
||||
body: body,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn block(body: Vec<Statement>) -> Self {
|
||||
LTExpr::Block { region: InputRegionTag::default(), statements: body }
|
||||
}
|
||||
}
|
||||
|
||||
impl Statement {
|
||||
pub fn while_loop(cond: LTExpr, body: Vec<Statement>) -> Self {
|
||||
Statement::WhileLoop {
|
||||
condition: cond,
|
||||
body,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -214,6 +214,7 @@ where It: Iterator<Item = (InputRegionTag, Result<LTIRToken, LexError>)>
|
|||
let _ = parse_expect(tokens, LTIRToken::StatementSep)?;
|
||||
|
||||
Ok(Statement::LetAssign {
|
||||
name_region,
|
||||
typ: match typ {
|
||||
Some((r,t)) => Some(Ok(t)),
|
||||
None => None
|
||||
|
@ -292,8 +293,19 @@ where It: Iterator<Item = (InputRegionTag, Result<LTIRToken, LexError>)>
|
|||
{
|
||||
match tokens.next() {
|
||||
Some((region, Ok(LTIRToken::Symbol(sym)))) => Ok(LTExpr::Symbol{ region, symbol: sym, typ: None }),
|
||||
Some((region, Ok(LTIRToken::Char(c)))) => Ok(LTExpr::lit_uint(c as u64)),
|
||||
Some((region, Ok(LTIRToken::Num(n)))) => Ok(LTExpr::lit_uint(n as u64)),
|
||||
Some((region, Ok(LTIRToken::Char(c)))) => Ok(
|
||||
LTExpr::Ascend {
|
||||
region: region.clone(),
|
||||
typ: match typectx.parse("Char ~ Unicode ~ ℤ_2^32") {
|
||||
Ok(t) => Ok(t),
|
||||
Err(e) => Err(TypeError::ParseError(e))
|
||||
},
|
||||
expr: Box::new(
|
||||
LTExpr::WordLiteral{ region, val: c as tisc::VM_Word }
|
||||
)
|
||||
}
|
||||
),
|
||||
Some((region, Ok(LTIRToken::Num(n)))) => Ok(LTExpr::WordLiteral{ region, val: n as tisc::VM_Word }),
|
||||
Some((region, Ok(_))) => Err((region, ParseError::UnexpectedToken)),
|
||||
Some((region, Err(err))) => Err((region, ParseError::LexError(err))),
|
||||
None => Err((InputRegionTag::default(), ParseError::UnexpectedEnd)),
|
||||
|
@ -345,7 +357,13 @@ where It: Iterator<Item = (InputRegionTag, Result<LTIRToken, LexError>)>
|
|||
break;
|
||||
}
|
||||
Ok(LTIRToken::BlockOpen) => {
|
||||
children.push(LTExpr::block(parse_statement_block(typectx, tokens)?));
|
||||
let region = region.clone();
|
||||
let statements = parse_statement_block(typectx, tokens)?;
|
||||
children.push(
|
||||
LTExpr::Block {
|
||||
region,
|
||||
statements
|
||||
});
|
||||
}
|
||||
Ok(LTIRToken::BlockClose) => {
|
||||
break;
|
||||
|
@ -368,6 +386,7 @@ where It: Iterator<Item = (InputRegionTag, Result<LTIRToken, LexError>)>
|
|||
};
|
||||
|
||||
if let Some(expr) = children.pop() {
|
||||
region.begin = expr.get_region().begin;
|
||||
children.push(LTExpr::Ascend {
|
||||
region: region.clone(),
|
||||
typ,
|
||||
|
@ -402,8 +421,10 @@ where It: Iterator<Item = (InputRegionTag, Result<LTIRToken, LexError>)>
|
|||
let _ = parse_expect(tokens, LTIRToken::ExprOpen)?;
|
||||
let cond = parse_expr(typectx, tokens)?;
|
||||
let _ = parse_expect(tokens, LTIRToken::ExprClose)?;
|
||||
let if_expr = LTExpr::block(parse_statement_block(typectx, tokens)?);
|
||||
let mut else_expr = LTExpr::block(vec![]);
|
||||
|
||||
let if_statements = parse_statement_block(typectx, tokens)?;
|
||||
let if_expr = LTExpr::Block{ region: region.clone(), statements: if_statements };
|
||||
let mut else_expr = LTExpr::Block{ region: InputRegionTag::default(), statements: vec![] };
|
||||
|
||||
if let Some((region, peektok)) = tokens.peek() {
|
||||
if let Ok(LTIRToken::Symbol(name)) = peektok {
|
||||
|
@ -445,8 +466,16 @@ where It: Iterator<Item = (InputRegionTag, Result<LTIRToken, LexError>)>
|
|||
|
||||
if children.len() > 1 {
|
||||
let head = children.remove(0);
|
||||
|
||||
let mut region = head.get_region();
|
||||
for c in children.iter() {
|
||||
let cr = c.get_region();
|
||||
region.begin = usize::min( region.begin, cr.begin );
|
||||
region.end = usize::max( region.end, cr.end );
|
||||
}
|
||||
|
||||
Ok(LTExpr::Application {
|
||||
region: InputRegionTag::default(),
|
||||
region,
|
||||
typ: None,
|
||||
head: Box::new(head),
|
||||
body: children,
|
||||
|
|
|
@ -138,6 +138,7 @@ impl ProcedureCompiler {
|
|||
}
|
||||
}
|
||||
Statement::LetAssign {
|
||||
name_region,
|
||||
typ,
|
||||
var_id,
|
||||
val_expr,
|
||||
|
@ -170,7 +171,7 @@ impl ProcedureCompiler {
|
|||
.declare_var(var_id.clone(), laddertypes::TypeTerm::unit());
|
||||
|
||||
self = self.compile_statement(&Statement::Assignment {
|
||||
name_region: InputRegionTag::default(),
|
||||
name_region: *name_region,
|
||||
var_id: var_id.clone(),
|
||||
val_expr: val_expr.clone(),
|
||||
}, false);
|
||||
|
|
Loading…
Reference in a new issue