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 a457e9b commit 8aa3972
Show file tree
Hide file tree
Showing 11 changed files with 158 additions and 38 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
4 changes: 2 additions & 2 deletions libflux/c/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void test_semantic() {

{
printf("Parsing to AST\n");
struct flux_ast_pkg_t *ast_pkg_foo = flux_parse("test", "package foo\nx = 1 + 1.0");
struct flux_ast_pkg_t *ast_pkg_foo = flux_parse("test", "package foo\nx = 1 + \"1.0\"");
assert(ast_pkg_foo != NULL);

printf("Analyzing (expect failure)\n");
Expand Down Expand Up @@ -115,7 +115,7 @@ void test_semantic() {

{
printf("Parsing to AST\n");
struct flux_ast_pkg_t *ast_pkg_foo = flux_parse("test", "package foo\nx = 1 + 1.0");
struct flux_ast_pkg_t *ast_pkg_foo = flux_parse("test", "package foo\nx = 1 + \"1.0\"");
assert(ast_pkg_foo != NULL);
printf("Find variable type v (expect failure)\n");
struct flux_buffer_t buf;
Expand Down
16 changes: 8 additions & 8 deletions libflux/go/libflux/buildinfo.gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,25 @@ var sourceHashes = map[string]string{
"libflux/src/core/scanner/unicode.rl.COPYING": "6cf2d5d26d52772ded8a5f0813f49f83dfa76006c5f398713be3854fe7bc4c7e",
"libflux/src/core/semantic/bootstrap.rs": "e6935092bc7cae45caab02dc9dd4725b4791fb5e2cea01555933cfa14edfc0e8",
"libflux/src/core/semantic/check.rs": "acb29602ee01f636818ba3522b3f110018abca3e7b4a6b75c29eec97856a324e",
"libflux/src/core/semantic/convert.rs": "f0821be66ba8fd1e1a177bf63ad125778dbb5c7a78091a7c52452ab159aecbe4",
"libflux/src/core/semantic/convert.rs": "d6a6c591088fa4833cf9e3fb67538d55488855d671c9e67302ef5ab856cf6ac7",
"libflux/src/core/semantic/env.rs": "e031d5b752d207a8f93bacd8515639e832735d5a85e90db76690aaeee8168127",
"libflux/src/core/semantic/flatbuffers/mod.rs": "244afed2e7cee6dc5a80a03a1c91d38ad1137bc2163640b59f464f383d7a01d5",
"libflux/src/core/semantic/flatbuffers/semantic_generated.rs": "ebd91d5eaa43f2604724661a0ccbd1645dde70cfb9834e0e0889badb2b17317b",
"libflux/src/core/semantic/flatbuffers/semantic_generated.rs": "26db557cbed4e3e3e966700d9d50d7d2d9600569bd3d2bbdeeb1a38fd7405e24",
"libflux/src/core/semantic/flatbuffers/tests.rs": "563d1c78bfc70473048611d1c4153951122aca030b775663f627f3754c806634",
"libflux/src/core/semantic/flatbuffers/types.rs": "cea742d4473952fb5767a7c2e746e6968b684b3fae6244440ca5a8b6a389435a",
"libflux/src/core/semantic/flatbuffers/types.rs": "92c979adebf156cd31a21b9a41417aa3b948a5201b97a42f02f1fe173304ca38",
"libflux/src/core/semantic/fresh.rs": "896e8132cdb731dbc70cdbc465c5020099af30dbe954be715f78a2b4cd8b738b",
"libflux/src/core/semantic/import.rs": "7b0a9259bb86fc887707ac442a71ca63ea1ef61b150a376d973d5dd3172e6ec6",
"libflux/src/core/semantic/infer.rs": "23fd3349fb08e950d521061c4bd7a10673816707bd7f26351aa959572dc0a408",
"libflux/src/core/semantic/mod.rs": "4d63d0471461c0f1baece0d2828ae237312d23707cdb17c59565704ca93195d2",
"libflux/src/core/semantic/nodes.rs": "bdf1a719fe6bec49fb5578c46c9ca938ac351590e0099bb39b5ed3e65d00eaf8",
"libflux/src/core/semantic/sub.rs": "9fd72f30c4ea5fde11c636160dc88271d34d6f49e2c5f95d32d22a500ef109b9",
"libflux/src/core/semantic/tests.rs": "d03edb332dd8e0d148c66aeccc347b5d7ead196bfaf448f809afe2f8418f6817",
"libflux/src/core/semantic/types.rs": "b4b62d253e3405d46084fa28c8f39802f81a3cb986cc82f5280e9fe2462bb84f",
"libflux/src/core/semantic/nodes.rs": "8efec9d310f93720e8bace604b687864d8016b422a2be86efed444f94cceb0b9",
"libflux/src/core/semantic/sub.rs": "85c2873cde6cceea40c2bdabecbdda72ec4a5d625c8d3225e85bcc048c936541",
"libflux/src/core/semantic/tests.rs": "3b0241d582c1e37a1c2baedd2061d10f22ef78295e352e20af5d6cfcd4dd8d1b",
"libflux/src/core/semantic/types.rs": "8f61d49f2ff93f4ebd2e1b2950061034d58a6e79e56a663f06fb57ff03635b58",
"libflux/src/core/semantic/walk/_walk.rs": "f13a98ba71c05b960bae2db66d87f30368bd1deea3b1d0013604afb7c7bba8b8",
"libflux/src/core/semantic/walk/mod.rs": "f0167952d639b075c45212d895aee87997e477a76446912a29ab6ed6a9c21325",
"libflux/src/core/semantic/walk/test_utils.rs": "317606227b28f607273e4ff6ac431e148f753cc20ea1812fa7b97ecb262b3f90",
"libflux/src/core/semantic/walk/walk_mut.rs": "4a4614a0459d07dbd4f0579028acf3897b82a9d3fa6ed59511c4512d786e1de6",
"libflux/src/core/tests/analyze_test.rs": "c49d81bdaa2275681990cdf8e18eb13adcbb54895ba0c2c49ab1a727d529a820",
"libflux/src/core/tests/analyze_test.rs": "b8552fa19819b326ad53eace2d0e227367321b9161085f167f45f811c3817208",
"libflux/src/flux/Cargo.toml": "ede8860c53d1fd5cc7bc730a090e615b5668b0c340ccc8b1b9dbed426b5c8f76",
"libflux/src/flux/benches/builtins.rs": "c60908c65ea51c225fccec19c44343af9103c950a91b23071ddb80292da708c8",
"libflux/src/flux/build.rs": "31a4f825297f9b79d1c8692a5fa3ff9211cb87d01650d147128d061588f75abd",
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 8aa3972

Please sign in to comment.