FEATURE: add Binary expression type derivation

This commit is contained in:
Jeremy Wall 2021-08-14 18:03:42 -04:00 committed by Jeremy Wall
parent 97c3a30973
commit b5c1418e30
6 changed files with 36 additions and 12 deletions

View File

@ -32,6 +32,8 @@ use crate::build::scope::Scope;
use crate::build::Val;
use crate::error::{BuildError, ErrorType::TypeFail};
use self::walk::Walker;
pub mod printer;
pub mod rewrite;
pub mod typecheck;
@ -272,8 +274,8 @@ value_enum!(
);
impl Shape {
pub fn merge(&self, compare: &Shape) -> Option<Self> {
match (self, compare) {
pub fn merge(&self, right: &Shape) -> Option<Self> {
match (self, right) {
(Shape::Str(_), Shape::Str(_))
| (Shape::Symbol(_), Shape::Symbol(_))
| (Shape::Boolean(_), Shape::Boolean(_))
@ -775,7 +777,7 @@ fn normalize_path(p: PathBuf) -> PathBuf {
return normalized;
}
impl walk::Walker for Rewriter {
impl Walker for Rewriter {
fn walk_statement_list(&mut self, stmts: Vec<&mut Statement>) {
for v in stmts {
self.walk_statement(v);
@ -1046,12 +1048,26 @@ impl Expression {
CastType::Float => Shape::Float(PositionedItem::new(0.0, def.pos.clone())),
CastType::Bool => Shape::Boolean(PositionedItem::new(true, def.pos.clone())),
},
Expression::Import(def) => {
// FIXME(jwall): What should this do?
Shape::Symbol(PositionedItem::new(
def.path.fragment.clone(),
def.path.pos.clone(),
))
Expression::Import(def) => Shape::Symbol(PositionedItem::new(
def.path.fragment.clone(),
def.path.pos.clone(),
)),
Expression::Binary(def) => {
let left_shape = def.left.derive_shape()?;
let right_shape = def.right.derive_shape()?;
match left_shape.merge(&right_shape) {
Some(shape) => shape,
None => {
return Err(BuildError::new(
format!(
"Expected {} value on right hand side of expression but got: {}",
left_shape.type_name(),
right_shape.type_name()
),
TypeFail,
));
}
}
}
_ => Shape::Empty(Position::new(0, 0, 0)),
};

View File

@ -13,7 +13,7 @@
// limitations under the License.
use std::path::PathBuf;
use crate::ast::walk::{Visitor, Walker};
use crate::ast::walk::Visitor;
use crate::ast::Expression;
pub struct Rewriter {

View File

@ -154,6 +154,10 @@ fn derive_shape_expressions() {
"bool(\"true\");",
Shape::Boolean(PositionedItem::new(true, Position::new(0, 0, 0))),
),
(
"1 + 1;",
Shape::Int(PositionedItem::new(1, Position::new(1, 1, 0))),
),
];
for (expr, shape) in expr_cases {

View File

@ -13,7 +13,7 @@
// limitations under the License.
//! Implements typechecking for the parsed ucg AST.
// FIXME(jwall): This probably just needs to disappear now.
use std::collections::BTreeMap;
use crate::ast::walk::Visitor;

View File

@ -35,6 +35,7 @@ where
Stderr: Write + Clone,
{
pub val_cache: BTreeMap<String, Rc<Value>>,
// TODO implement a shape cache here.
pub op_cache: cache::Ops,
pub converter_registry: ConverterRegistry,
pub importer_registry: ImporterRegistry,

View File

@ -18,7 +18,7 @@ use crate::ast::rewrite::Rewriter;
use crate::ast::walk::Walker;
use crate::ast::{
BinaryExprType, BinaryOpDef, Expression, FormatArgs, FuncOpDef, Position, PositionedItem,
SelectDef, Statement, TemplatePart, Token, TokenType, Value,
SelectDef, Shape, Statement, TemplatePart, Token, TokenType, Value,
};
use crate::build::format::{ExpressionTemplate, SimpleTemplate, TemplateParser};
use crate::build::opcode::Primitive;
@ -30,6 +30,7 @@ pub struct AST();
pub struct OpsMap {
pub ops: Vec<Op>,
pub pos: Vec<Position>,
pub shape_map: BTreeMap<String, Shape>,
pub links: BTreeMap<String, Position>,
}
@ -38,6 +39,8 @@ impl OpsMap {
OpsMap {
ops: Vec::new(),
pos: Vec::new(),
// TODO(jwall): Populate shapes when translating into opcodes.
shape_map: BTreeMap::new(),
links: BTreeMap::new(),
}
}