Skip to content

Commit

Permalink
feat(type_inference): added NumericDefaultInt cons
Browse files Browse the repository at this point in the history
 - Added NumericDefaultInt constraint
 - Updated IntegerLit semantic node to have monotype value
 - Updated semantic analysis to convert all NumericDefaultInt to int in final pass
  • Loading branch information
Akhil Jakatdar committed Oct 13, 2020
1 parent a093a23 commit dc891ec
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 28 deletions.
4 changes: 4 additions & 0 deletions docs/SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,10 @@ Int, Uint, and Float types are Divisible.

Int, Uint, and Float types are Numeric.

##### Numeric Default Int Constraint

Int, Uint, and Float types are Numeric and can default to int if not type inferred.

##### Comparable Constraint

Comparable types are those the binary comparison operators `<`, `<=`, `>`, or `>=` accept.
Expand Down
29 changes: 28 additions & 1 deletion libflux/src/core/semantic/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -666,10 +666,11 @@ fn convert_float_literal(lit: ast::FloatLit, _: &mut Fresher) -> Result<FloatLit
})
}

fn convert_integer_literal(lit: ast::IntegerLit, _: &mut Fresher) -> Result<IntegerLit> {
fn convert_integer_literal(lit: ast::IntegerLit, fresher: &mut Fresher) -> Result<IntegerLit> {
Ok(IntegerLit {
loc: lit.base.location,
value: lit.value,
typ: MonoType::Var(fresher.fresh()),
})
}

Expand Down Expand Up @@ -995,6 +996,7 @@ mod tests {
value: Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 10,
typ: MonoType::Int,
}),
}],
})),
Expand Down Expand Up @@ -1065,6 +1067,8 @@ mod tests {
value: Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 10,
typ: MonoType::Int,

}),
}],
})),
Expand Down Expand Up @@ -1151,6 +1155,8 @@ mod tests {
value: Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 10,
typ: MonoType::Int,

}),
},
Property {
Expand All @@ -1162,6 +1168,8 @@ mod tests {
value: Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 11,
typ: MonoType::Int,

}),
},
],
Expand Down Expand Up @@ -1452,6 +1460,8 @@ mod tests {
value: Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 5,
typ: MonoType::Int,

}),
},
],
Expand Down Expand Up @@ -1728,6 +1738,8 @@ mod tests {
value: Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 2,
typ: MonoType::Int,

}),
},
Property {
Expand All @@ -1739,6 +1751,8 @@ mod tests {
value: Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 3,
typ: MonoType::Int,

}),
},
],
Expand Down Expand Up @@ -1861,6 +1875,7 @@ mod tests {
value: Some(ast::Expression::Integer(ast::IntegerLit {
base: b.clone(),
value: 42,

})),
comma: None,
}],
Expand Down Expand Up @@ -1900,6 +1915,7 @@ mod tests {
default: Some(Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 0,
typ: MonoType::Int,
})),
},
FunctionParameter {
Expand All @@ -1912,6 +1928,7 @@ mod tests {
default: Some(Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 0,
typ: MonoType::Int,
})),
},
FunctionParameter {
Expand Down Expand Up @@ -1975,6 +1992,7 @@ mod tests {
value: Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 42,
typ: MonoType::Int,
}),
}],
})),
Expand Down Expand Up @@ -2312,6 +2330,7 @@ mod tests {
pipe: Some(Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 3,
typ: MonoType::Int,
})),
callee: Expression::Identifier(IdentifierExpr {
loc: b.location.clone(),
Expand All @@ -2327,6 +2346,7 @@ mod tests {
value: Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 2,
typ: MonoType::Int,
}),
}],
})),
Expand Down Expand Up @@ -2400,6 +2420,7 @@ mod tests {
default: Some(Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 0,
typ: MonoType::Int,
})),
};
let default1 = FunctionParameter {
Expand All @@ -2412,6 +2433,7 @@ mod tests {
default: Some(Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 1,
typ: MonoType::Int,
})),
};
let default2 = FunctionParameter {
Expand All @@ -2424,6 +2446,7 @@ mod tests {
default: Some(Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 2,
typ: MonoType::Int,
})),
};
let no_default = FunctionParameter {
Expand Down Expand Up @@ -2520,6 +2543,7 @@ mod tests {
index: Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 3,
typ: MonoType::Int,
}),
})),
})],
Expand Down Expand Up @@ -2593,11 +2617,13 @@ mod tests {
index: Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 3,
typ: MonoType::Int,
}),
})),
index: Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 5,
typ: MonoType::Int,
}),
})),
})],
Expand Down Expand Up @@ -2671,6 +2697,7 @@ mod tests {
index: Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 3,
typ: MonoType::Int,
}),
})),
})],
Expand Down
11 changes: 8 additions & 3 deletions libflux/src/core/semantic/flatbuffers/semantic_generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,11 @@ pub mod fbsemantic {
Record = 7,
Negatable = 8,
Timeable = 9,
NumericDefaultInt = 10,
}

const ENUM_MIN_KIND: u8 = 0;
const ENUM_MAX_KIND: u8 = 9;
const ENUM_MAX_KIND: u8 = 10;

impl<'a> flatbuffers::Follow<'a> for Kind {
type Inner = Self;
Expand Down Expand Up @@ -202,9 +203,11 @@ pub mod fbsemantic {
flatbuffers::emplace_scalar::<Kind>(dst, *self);
}
}


//TODO: add global variable for number of constraints
#[allow(non_camel_case_types)]
const ENUM_VALUES_KIND: [Kind; 10] = [
const ENUM_VALUES_KIND: [Kind; 11] = [
Kind::Addable,
Kind::Subtractable,
Kind::Divisible,
Expand All @@ -215,10 +218,11 @@ pub mod fbsemantic {
Kind::Record,
Kind::Negatable,
Kind::Timeable,
Kind::NumericDefaultInt,
];

#[allow(non_camel_case_types)]
const ENUM_NAMES_KIND: [&'static str; 10] = [
const ENUM_NAMES_KIND: [&'static str; 11] = [
"Addable",
"Subtractable",
"Divisible",
Expand All @@ -229,6 +233,7 @@ pub mod fbsemantic {
"Record",
"Negatable",
"Timeable",
"NumericDefaultInt",
];

pub fn enum_name_kind(e: Kind) -> &'static str {
Expand Down
2 changes: 2 additions & 0 deletions libflux/src/core/semantic/flatbuffers/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ impl From<fb::Kind> for Kind {
fb::Kind::Subtractable => Kind::Subtractable,
fb::Kind::Divisible => Kind::Divisible,
fb::Kind::Numeric => Kind::Numeric,
fb::Kind::NumericDefaultInt => Kind::NumericDefaultInt,
fb::Kind::Comparable => Kind::Comparable,
fb::Kind::Equatable => Kind::Equatable,
fb::Kind::Nullable => Kind::Nullable,
Expand All @@ -100,6 +101,7 @@ impl From<Kind> for fb::Kind {
Kind::Subtractable => fb::Kind::Subtractable,
Kind::Divisible => fb::Kind::Divisible,
Kind::Numeric => fb::Kind::Numeric,
Kind::NumericDefaultInt => fb::Kind::NumericDefaultInt,
Kind::Comparable => fb::Kind::Comparable,
Kind::Equatable => fb::Kind::Equatable,
Kind::Nullable => fb::Kind::Nullable,
Expand Down
22 changes: 17 additions & 5 deletions libflux/src/core/semantic/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ impl Expression {
Expression::Call(e) => e.typ.clone(),
Expression::Conditional(e) => e.alternate.type_of(),
Expression::StringExpr(_) => MonoType::String,
Expression::Integer(_) => MonoType::Int,
Expression::Integer(e) => e.typ.clone(),
Expression::Float(_) => MonoType::Float,
Expression::StringLit(_) => MonoType::String,
Expression::Duration(_) => MonoType::Duration,
Expand Down Expand Up @@ -543,10 +543,9 @@ impl VariableAssgn {

let mut kinds = TvarKinds::new();
let sub = infer::solve(&constraints, &mut kinds, f)?;

// Apply substitution to the type environment
let mut env = env.apply(&sub);

let t = self.init.type_of().apply(&sub);
let p = infer::generalize(&env, &kinds, t);

Expand Down Expand Up @@ -1647,13 +1646,24 @@ impl BooleanLit {
pub struct IntegerLit {
pub loc: ast::SourceLocation,
pub value: i64,
#[derivative(PartialEq = "ignore")]
pub typ: MonoType,
}

impl IntegerLit {
fn infer(&self, env: Environment) -> Result {
Ok((env, Constraints::empty()))
let cons = Constraints::from(vec![
Constraint::Kind {
act: self.typ.clone(),
exp: Kind::NumericDefaultInt,
loc: self.loc.clone(),
}

]);
Ok((env, cons))
}
fn apply(self, _: &Substitution) -> Self {
fn apply(mut self, sub: &Substitution) -> Self {
self.typ = self.typ.apply(&sub);
self
}
}
Expand Down Expand Up @@ -2031,6 +2041,7 @@ mod tests {
pipe: Some(Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 3,
typ: MonoType::Int,
})),
callee: Expression::Identifier(IdentifierExpr {
loc: b.location.clone(),
Expand All @@ -2046,6 +2057,7 @@ mod tests {
value: Expression::Integer(IntegerLit {
loc: b.location.clone(),
value: 2,
typ: MonoType::Int,
}),
}],
})),
Expand Down
4 changes: 4 additions & 0 deletions libflux/src/core/semantic/sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ impl Substitution {
}
}

pub fn insert(&mut self, k: Tvar, v: MonoType) {
self.0.insert(k, v);
}

pub fn merge(self, with: Substitution) -> Substitution {
let applied: SubstitutionMap = self
.0
Expand Down
Loading

0 comments on commit dc891ec

Please sign in to comment.