All blocks have result types.
This commit is contained in:
parent
c465cdf9a4
commit
396a6d020b
13 changed files with 71 additions and 34 deletions
|
@ -33,8 +33,8 @@ impl Clause {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResultType for Clause {
|
impl ResultType for Clause {
|
||||||
fn result_type(&self) -> Option<&TyIdx> {
|
fn result_type(&self) -> &TyIdx {
|
||||||
Some(&self.result_type)
|
&self.result_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,11 @@ fn fmt_types(buffer: &mut String, context: &Context) {
|
||||||
} else if ty.is_unresolved() {
|
} else if ty.is_unresolved() {
|
||||||
buffer.push_str("unknown type");
|
buffer.push_str("unknown type");
|
||||||
}
|
}
|
||||||
buffer.push_str("\n")
|
if let Some(location) = ty.get_location() {
|
||||||
|
buffer.push_str(&format!(" defined at {}\n", location));
|
||||||
|
} else {
|
||||||
|
buffer.push_str("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +199,7 @@ fn fmt_functions(mut buffer: &mut String, context: &Context) {
|
||||||
}
|
}
|
||||||
buffer.push_str(&format!(
|
buffer.push_str(&format!(
|
||||||
" -> {}\n",
|
" -> {}\n",
|
||||||
fmt_ty_name(clause.result_type().unwrap(), &context)
|
fmt_ty_name(clause.result_type(), &context)
|
||||||
));
|
));
|
||||||
|
|
||||||
let mut jumps = Vec::new();
|
let mut jumps = Vec::new();
|
||||||
|
@ -530,7 +534,7 @@ fn fmt_methods(mut buffer: &mut String, context: &Context) {
|
||||||
}
|
}
|
||||||
buffer.push_str(&format!(
|
buffer.push_str(&format!(
|
||||||
" -> {}\n",
|
" -> {}\n",
|
||||||
fmt_ty_name(clause.result_type().unwrap(), &context)
|
fmt_ty_name(clause.result_type(), &context)
|
||||||
));
|
));
|
||||||
|
|
||||||
let mut jumps = vec![clause.body().clone()];
|
let mut jumps = vec![clause.body().clone()];
|
||||||
|
|
|
@ -88,20 +88,20 @@ impl Locatable for &mut Function {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResultType for Function {
|
impl ResultType for Function {
|
||||||
fn result_type(&self) -> Option<&TyIdx> {
|
fn result_type(&self) -> &TyIdx {
|
||||||
Some(&self.return_type)
|
&self.return_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResultType for &Function {
|
impl ResultType for &Function {
|
||||||
fn result_type(&self) -> Option<&TyIdx> {
|
fn result_type(&self) -> &TyIdx {
|
||||||
Some(&self.return_type)
|
&self.return_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResultType for &mut Function {
|
impl ResultType for &mut Function {
|
||||||
fn result_type(&self) -> Option<&TyIdx> {
|
fn result_type(&self) -> &TyIdx {
|
||||||
Some(&self.return_type)
|
&self.return_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::block::BlockIdx;
|
use crate::block::BlockIdx;
|
||||||
use crate::clause::Clauseable;
|
use crate::clause::Clauseable;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
|
use crate::ty::ResultType;
|
||||||
|
|
||||||
pub fn pass<T: Clauseable>(fun: &mut T, mut context: &mut Context) {
|
pub fn pass<T: Clauseable>(fun: &mut T, mut context: &mut Context) {
|
||||||
for clause in fun.clauses() {
|
for clause in fun.clauses() {
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::ty::ResultType;
|
||||||
pub fn pass<T: Clauseable + Locatable + ResultType>(fun: &mut T, context: &mut Context) {
|
pub fn pass<T: Clauseable + Locatable + ResultType>(fun: &mut T, context: &mut Context) {
|
||||||
for clause in fun.clauses() {
|
for clause in fun.clauses() {
|
||||||
let block_idx = clause.body();
|
let block_idx = clause.body();
|
||||||
let ty_idx = clause.result_type().unwrap();
|
let ty_idx = clause.result_type();
|
||||||
let result_type = context.get_block(block_idx).unwrap().result_type().clone();
|
let result_type = context.get_block(block_idx).unwrap().result_type().clone();
|
||||||
let ty = context.get_type_mut(ty_idx).unwrap();
|
let ty = context.get_type_mut(ty_idx).unwrap();
|
||||||
ty.resolve(&result_type);
|
ty.resolve(&result_type);
|
||||||
|
|
|
@ -43,6 +43,7 @@ pub fn pass(ir: &mut IR, context: &mut Context) {
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::ir::builder::Builder;
|
use crate::ir::builder::Builder;
|
||||||
|
use crate::location::Location;
|
||||||
use huia_parser::ast::Term;
|
use huia_parser::ast::Term;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -50,6 +51,7 @@ mod test {
|
||||||
let terms = Term::input("3 * 2").unwrap();
|
let terms = Term::input("3 * 2").unwrap();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
|
builder.push_block(context.unknown_type(Location::test()));
|
||||||
|
|
||||||
for term in terms {
|
for term in terms {
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
|
|
|
@ -27,6 +27,7 @@ pub fn pass(ir: &mut IR, context: &mut Context) {
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::ir::builder::Builder;
|
use crate::ir::builder::Builder;
|
||||||
|
use crate::location::Location;
|
||||||
use huia_parser::ast::Term;
|
use huia_parser::ast::Term;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -34,6 +35,7 @@ mod test {
|
||||||
let terms = Term::input("!3").unwrap();
|
let terms = Term::input("!3").unwrap();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
|
builder.push_block(context.unknown_type(Location::test()));
|
||||||
|
|
||||||
for term in terms {
|
for term in terms {
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
|
|
|
@ -71,6 +71,7 @@ fn perform_f64_infix_fold(op: &BinOp, lhs: f64, rhs: f64) -> Option<f64> {
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::ir::builder::Builder;
|
use crate::ir::builder::Builder;
|
||||||
|
use crate::location::Location;
|
||||||
use huia_parser::ast::Term;
|
use huia_parser::ast::Term;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -78,6 +79,7 @@ mod test {
|
||||||
let term = Term::input("3 * 2 + 13 / 2").unwrap()[0].clone();
|
let term = Term::input("3 * 2 + 13 / 2").unwrap()[0].clone();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
|
builder.push_block(context.unknown_type(Location::test()));
|
||||||
|
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
let mut ir = builder.pop_ir().unwrap();
|
let mut ir = builder.pop_ir().unwrap();
|
||||||
|
@ -92,6 +94,7 @@ mod test {
|
||||||
let term = Term::input("1.5 * 2.0 / 3.0").unwrap()[0].clone();
|
let term = Term::input("1.5 * 2.0 / 3.0").unwrap()[0].clone();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
|
builder.push_block(context.unknown_type(Location::test()));
|
||||||
|
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
let mut ir = builder.pop_ir().unwrap();
|
let mut ir = builder.pop_ir().unwrap();
|
||||||
|
|
|
@ -54,6 +54,8 @@ pub fn pass(ir: &mut IR, context: &mut Context) {
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::ir::builder::Builder;
|
use crate::ir::builder::Builder;
|
||||||
|
use crate::location::Location;
|
||||||
|
use crate::ty::ResultType;
|
||||||
use huia_parser::ast::Term;
|
use huia_parser::ast::Term;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -61,6 +63,7 @@ mod test {
|
||||||
let term = Term::input("!3").unwrap()[0].clone();
|
let term = Term::input("!3").unwrap()[0].clone();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
|
builder.push_block(context.unknown_type(Location::test()));
|
||||||
|
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
let mut ir = builder.pop_ir().unwrap();
|
let mut ir = builder.pop_ir().unwrap();
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::location::Locatable;
|
||||||
use crate::location::Location as Loc;
|
use crate::location::Location as Loc;
|
||||||
use crate::method::{Method, MethodIdx, Modifier};
|
use crate::method::{Method, MethodIdx, Modifier};
|
||||||
use crate::stable::StringIdx;
|
use crate::stable::StringIdx;
|
||||||
use crate::ty::TyIdx;
|
use crate::ty::{ResultType, TyIdx};
|
||||||
use huia_parser::ast::{Identifier, Location, NodeType, Term, TypeSpec, Value};
|
use huia_parser::ast::{Identifier, Location, NodeType, Term, TypeSpec, Value};
|
||||||
|
|
||||||
/// The Builder is a simple stack machine for converting AST into IR.
|
/// The Builder is a simple stack machine for converting AST into IR.
|
||||||
|
@ -69,7 +69,7 @@ impl Builder {
|
||||||
context.reference_type(&name, location.clone())
|
context.reference_type(&name, location.clone())
|
||||||
}
|
}
|
||||||
else if op.is_arithmetic() {
|
else if op.is_arithmetic() {
|
||||||
lhs.result_type()
|
lhs.result_type().clone()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
panic!("Operator {:?} is neither arithmetic nor logical", op);
|
panic!("Operator {:?} is neither arithmetic nor logical", op);
|
||||||
|
@ -123,7 +123,7 @@ impl Builder {
|
||||||
self.build(rhs.clone(), &mut context);
|
self.build(rhs.clone(), &mut context);
|
||||||
let rhs = self.pop_ir().unwrap();
|
let rhs = self.pop_ir().unwrap();
|
||||||
self.env_set(&name, &rhs.result_type());
|
self.env_set(&name, &rhs.result_type());
|
||||||
self.push_ir(IR::new_set_local(rhs.result_type(), location, name, rhs));
|
self.push_ir(IR::new_set_local(rhs.result_type().clone(), location, name, rhs));
|
||||||
}
|
}
|
||||||
NodeType::Float => {
|
NodeType::Float => {
|
||||||
let ty_idx = context.constant_string("Huia.Native.Float");
|
let ty_idx = context.constant_string("Huia.Native.Float");
|
||||||
|
@ -171,8 +171,8 @@ impl Builder {
|
||||||
if let Some(last_ir) = self.pop_ir() {
|
if let Some(last_ir) = self.pop_ir() {
|
||||||
let rt = context.get_type_mut(&result_type).unwrap();
|
let rt = context.get_type_mut(&result_type).unwrap();
|
||||||
rt.resolve(&last_ir.result_type());
|
rt.resolve(&last_ir.result_type());
|
||||||
self.push_ir(IR::new_set_local(last_ir.result_type(), location.clone(), value_var_name.clone(), last_ir.clone()));
|
self.push_ir(IR::new_set_local(last_ir.result_type().clone(), location.clone(), value_var_name.clone(), last_ir.clone()));
|
||||||
self.push_ir(IR::new_jump(last_ir.result_type(), location.clone(), following_block_idx.into()));
|
self.push_ir(IR::new_jump(last_ir.result_type().clone(), location.clone(), following_block_idx.into()));
|
||||||
} else {
|
} else {
|
||||||
self.push_ir(IR::new_jump(result_type.clone(), location.clone(), following_block_idx.into()));
|
self.push_ir(IR::new_jump(result_type.clone(), location.clone(), following_block_idx.into()));
|
||||||
}
|
}
|
||||||
|
@ -198,12 +198,12 @@ impl Builder {
|
||||||
|
|
||||||
if let Some(last_ir) = self.pop_ir() {
|
if let Some(last_ir) = self.pop_ir() {
|
||||||
let rt = context.get_type(&result_type).unwrap();
|
let rt = context.get_type(&result_type).unwrap();
|
||||||
if rt.target().unwrap() != &last_ir.result_type() {
|
if rt.target().unwrap() != last_ir.result_type() {
|
||||||
context.compile_error("Both branches of an if statement must result in the same type.", location.clone(), ErrorKind::InconsistentBranchTypes);
|
context.compile_error("Both branches of an if statement must result in the same type.", location.clone(), ErrorKind::InconsistentBranchTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.push_ir(IR::new_set_local(last_ir.result_type(), location.clone(), value_var_name.clone(), last_ir.clone()));
|
self.push_ir(IR::new_set_local(last_ir.result_type().clone(), location.clone(), value_var_name.clone(), last_ir.clone()));
|
||||||
self.push_ir(IR::new_jump(last_ir.result_type(), location.clone(), following_block_idx.into()));
|
self.push_ir(IR::new_jump(last_ir.result_type().clone(), location.clone(), following_block_idx.into()));
|
||||||
} else {
|
} else {
|
||||||
self.push_ir(IR::new_jump(result_type.clone(), location.clone(), following_block_idx.into()));
|
self.push_ir(IR::new_jump(result_type.clone(), location.clone(), following_block_idx.into()));
|
||||||
}
|
}
|
||||||
|
@ -454,7 +454,7 @@ impl Builder {
|
||||||
let (op, rhs) = node.unary().unwrap();
|
let (op, rhs) = node.unary().unwrap();
|
||||||
self.build(rhs.clone(), &mut context);
|
self.build(rhs.clone(), &mut context);
|
||||||
let rhs = self.pop_ir().unwrap();
|
let rhs = self.pop_ir().unwrap();
|
||||||
let result_type = rhs.result_type();
|
let result_type = rhs.result_type().clone();
|
||||||
self.push_ir(IR::new_unary(
|
self.push_ir(IR::new_unary(
|
||||||
result_type,
|
result_type,
|
||||||
location,
|
location,
|
||||||
|
@ -524,7 +524,7 @@ impl Builder {
|
||||||
self.push_ir(last_ir);
|
self.push_ir(last_ir);
|
||||||
} else {
|
} else {
|
||||||
self.push_ir(IR::new_return(
|
self.push_ir(IR::new_return(
|
||||||
last_ir.result_type(),
|
last_ir.result_type().clone(),
|
||||||
last_ir.get_location().clone(),
|
last_ir.get_location().clone(),
|
||||||
last_ir,
|
last_ir,
|
||||||
));
|
));
|
||||||
|
@ -668,7 +668,7 @@ impl Builder {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_block(&mut self, result_type: TyIdx) {
|
pub fn push_block(&mut self, result_type: TyIdx) {
|
||||||
match self.peek_block() {
|
match self.peek_block() {
|
||||||
Some(ref block) => {
|
Some(ref block) => {
|
||||||
let env = block.env().clone();
|
let env = block.env().clone();
|
||||||
|
@ -707,6 +707,7 @@ mod test {
|
||||||
let term = Term::input(":marty").unwrap()[0].clone();
|
let term = Term::input(":marty").unwrap()[0].clone();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
let ir = builder.pop_ir().unwrap();
|
let ir = builder.pop_ir().unwrap();
|
||||||
assert!(ir.is_constant());
|
assert!(ir.is_constant());
|
||||||
|
@ -718,6 +719,7 @@ mod test {
|
||||||
let term = Term::input("true").unwrap()[0].clone();
|
let term = Term::input("true").unwrap()[0].clone();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
let ir = builder.pop_ir().unwrap();
|
let ir = builder.pop_ir().unwrap();
|
||||||
assert!(ir.is_constant());
|
assert!(ir.is_constant());
|
||||||
|
@ -729,6 +731,7 @@ mod test {
|
||||||
let term = Term::input("1.23").unwrap()[0].clone();
|
let term = Term::input("1.23").unwrap()[0].clone();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
let ir = builder.pop_ir().unwrap();
|
let ir = builder.pop_ir().unwrap();
|
||||||
assert!(ir.is_constant());
|
assert!(ir.is_constant());
|
||||||
|
@ -740,6 +743,7 @@ mod test {
|
||||||
let term = Term::input(r#" "Marty McFly" "#).unwrap()[0].clone();
|
let term = Term::input(r#" "Marty McFly" "#).unwrap()[0].clone();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
let ir = builder.pop_ir().unwrap();
|
let ir = builder.pop_ir().unwrap();
|
||||||
assert!(ir.is_constant());
|
assert!(ir.is_constant());
|
||||||
|
@ -751,6 +755,7 @@ mod test {
|
||||||
let term = Term::input(r#" MartyMcFly "#).unwrap()[0].clone();
|
let term = Term::input(r#" MartyMcFly "#).unwrap()[0].clone();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
let ir = builder.pop_ir().unwrap();
|
let ir = builder.pop_ir().unwrap();
|
||||||
assert!(ir.is_type_reference());
|
assert!(ir.is_type_reference());
|
||||||
|
@ -762,6 +767,7 @@ mod test {
|
||||||
let term = Term::input(r#" [1, 2, 3] "#).unwrap()[0].clone();
|
let term = Term::input(r#" [1, 2, 3] "#).unwrap()[0].clone();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
let ir = builder.pop_ir().unwrap();
|
let ir = builder.pop_ir().unwrap();
|
||||||
assert!(ir.is_constant());
|
assert!(ir.is_constant());
|
||||||
|
@ -774,6 +780,7 @@ mod test {
|
||||||
let term = Term::input(r#" { a: 2, :b => 3 } "#).unwrap()[0].clone();
|
let term = Term::input(r#" { a: 2, :b => 3 } "#).unwrap()[0].clone();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
let ir = builder.pop_ir().unwrap();
|
let ir = builder.pop_ir().unwrap();
|
||||||
assert!(ir.is_constant());
|
assert!(ir.is_constant());
|
||||||
|
@ -787,6 +794,7 @@ mod test {
|
||||||
let term = Term::input(r#" if true do 123 end "#).unwrap()[0].clone();
|
let term = Term::input(r#" if true do 123 end "#).unwrap()[0].clone();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
|
|
||||||
// Pop the follower block off the block stack.
|
// Pop the follower block off the block stack.
|
||||||
|
@ -803,6 +811,7 @@ mod test {
|
||||||
let term = Term::input(r#" if true do 123 else 456 end "#).unwrap()[0].clone();
|
let term = Term::input(r#" if true do 123 else 456 end "#).unwrap()[0].clone();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
|
|
||||||
// Pop the follower block off the block stack.
|
// Pop the follower block off the block stack.
|
||||||
|
@ -820,6 +829,7 @@ mod test {
|
||||||
let term = Term::input(r#" 1 + 2 "#).unwrap()[0].clone();
|
let term = Term::input(r#" 1 + 2 "#).unwrap()[0].clone();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
let ir = builder.pop_ir().unwrap();
|
let ir = builder.pop_ir().unwrap();
|
||||||
assert!(ir.is_infix());
|
assert!(ir.is_infix());
|
||||||
|
@ -831,6 +841,7 @@ mod test {
|
||||||
let term = Term::input(r#" Delorean { speed: 88 } "#).unwrap()[0].clone();
|
let term = Term::input(r#" Delorean { speed: 88 } "#).unwrap()[0].clone();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
let ir = builder.pop_ir().unwrap();
|
let ir = builder.pop_ir().unwrap();
|
||||||
assert!(ir.is_constructor());
|
assert!(ir.is_constructor());
|
||||||
|
@ -843,6 +854,7 @@ mod test {
|
||||||
let term = Term::input(r#" +88 "#).unwrap()[0].clone();
|
let term = Term::input(r#" +88 "#).unwrap()[0].clone();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
let ir = builder.pop_ir().unwrap();
|
let ir = builder.pop_ir().unwrap();
|
||||||
assert!(ir.is_unary());
|
assert!(ir.is_unary());
|
||||||
|
@ -854,6 +866,7 @@ mod test {
|
||||||
let terms = Term::input(" let x = 1\n x(123) ").unwrap();
|
let terms = Term::input(" let x = 1\n x(123) ").unwrap();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
for term in terms {
|
for term in terms {
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
}
|
}
|
||||||
|
@ -867,6 +880,7 @@ mod test {
|
||||||
let term = Term::input(r#" let x = 123 "#).unwrap()[0].clone();
|
let term = Term::input(r#" let x = 123 "#).unwrap()[0].clone();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
let ir = builder.pop_ir().unwrap();
|
let ir = builder.pop_ir().unwrap();
|
||||||
assert!(ir.is_set_local());
|
assert!(ir.is_set_local());
|
||||||
|
@ -878,6 +892,7 @@ mod test {
|
||||||
let term = Term::file("type Delorean(speed: Integer)").unwrap()[0].clone();
|
let term = Term::file("type Delorean(speed: Integer)").unwrap()[0].clone();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
assert!(context.find_type("Delorean").is_some());
|
assert!(context.find_type("Delorean").is_some());
|
||||||
assert!(context.find_type("Integer").is_some());
|
assert!(context.find_type("Integer").is_some());
|
||||||
|
@ -888,6 +903,7 @@ mod test {
|
||||||
let term = Term::file("trait TimeMachine").unwrap()[0].clone();
|
let term = Term::file("trait TimeMachine").unwrap()[0].clone();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
assert!(context.find_type("TimeMachine").is_some());
|
assert!(context.find_type("TimeMachine").is_some());
|
||||||
}
|
}
|
||||||
|
@ -905,6 +921,7 @@ mod test {
|
||||||
.clone();
|
.clone();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
assert!(context.find_type("Delorean").is_some());
|
assert!(context.find_type("Delorean").is_some());
|
||||||
assert!(context.find_type("TimeMachine").is_some());
|
assert!(context.find_type("TimeMachine").is_some());
|
||||||
|
@ -915,6 +932,7 @@ mod test {
|
||||||
let term = Term::input(r#"fn (speed: Integer) do "WAT" end"#).unwrap()[0].clone();
|
let term = Term::input(r#"fn (speed: Integer) do "WAT" end"#).unwrap()[0].clone();
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
let ir = builder.pop_ir().unwrap();
|
let ir = builder.pop_ir().unwrap();
|
||||||
assert!(ir.is_function());
|
assert!(ir.is_function());
|
||||||
|
@ -964,9 +982,7 @@ mod test {
|
||||||
|
|
||||||
let mut builder = Builder::default();
|
let mut builder = Builder::default();
|
||||||
let mut context = Context::test();
|
let mut context = Context::test();
|
||||||
|
builder.push_block(context.unknown_type(Loc::test()));
|
||||||
builder.build(term, &mut context);
|
builder.build(term, &mut context);
|
||||||
|
|
||||||
// println!("context: {:#?}", context);
|
|
||||||
// assert!(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::context::Context;
|
||||||
use crate::function::FunctionIdx;
|
use crate::function::FunctionIdx;
|
||||||
use crate::location::Location;
|
use crate::location::Location;
|
||||||
use crate::stable::StringIdx;
|
use crate::stable::StringIdx;
|
||||||
use crate::ty::TyIdx;
|
use crate::ty::{ResultType, TyIdx};
|
||||||
use huia_parser::ast::binary::Operator as BinOp;
|
use huia_parser::ast::binary::Operator as BinOp;
|
||||||
use huia_parser::ast::unary::Operator as UnOp;
|
use huia_parser::ast::unary::Operator as UnOp;
|
||||||
|
|
||||||
|
@ -526,10 +526,6 @@ impl IR {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn result_type(&self) -> TyIdx {
|
|
||||||
self.result_type.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_kind(&mut self, kind: IRKind) {
|
pub fn set_kind(&mut self, kind: IRKind) {
|
||||||
self.kind = kind;
|
self.kind = kind;
|
||||||
}
|
}
|
||||||
|
@ -539,6 +535,12 @@ impl IR {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ResultType for IR {
|
||||||
|
fn result_type(&self) -> &TyIdx {
|
||||||
|
&self.result_type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum IRKind {
|
pub enum IRKind {
|
||||||
/// Call the provided callee with arguments.
|
/// Call the provided callee with arguments.
|
||||||
|
|
|
@ -159,8 +159,8 @@ impl Locatable for &mut Method {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResultType for &mut Method {
|
impl ResultType for &mut Method {
|
||||||
fn result_type(&self) -> Option<&TyIdx> {
|
fn result_type(&self) -> &TyIdx {
|
||||||
Some(&self.return_type)
|
&self.return_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,10 @@ impl Ty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_location(&self) -> Option<&Location> {
|
||||||
|
self.location.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_prop_type(&self, name: &StringIdx) -> Option<&TyIdx> {
|
pub fn get_prop_type(&self, name: &StringIdx) -> Option<&TyIdx> {
|
||||||
match self.inner {
|
match self.inner {
|
||||||
TyInner::Type { ref properties } => properties.get(name),
|
TyInner::Type { ref properties } => properties.get(name),
|
||||||
|
@ -369,5 +373,5 @@ enum TyInner {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ResultType {
|
pub trait ResultType {
|
||||||
fn result_type(&self) -> Option<&TyIdx>;
|
fn result_type(&self) -> &TyIdx;
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue