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::build::Val;
use crate::error::{BuildError, ErrorType::TypeFail}; use crate::error::{BuildError, ErrorType::TypeFail};
use self::walk::Walker;
pub mod printer; pub mod printer;
pub mod rewrite; pub mod rewrite;
pub mod typecheck; pub mod typecheck;
@ -272,8 +274,8 @@ value_enum!(
); );
impl Shape { impl Shape {
pub fn merge(&self, compare: &Shape) -> Option<Self> { pub fn merge(&self, right: &Shape) -> Option<Self> {
match (self, compare) { match (self, right) {
(Shape::Str(_), Shape::Str(_)) (Shape::Str(_), Shape::Str(_))
| (Shape::Symbol(_), Shape::Symbol(_)) | (Shape::Symbol(_), Shape::Symbol(_))
| (Shape::Boolean(_), Shape::Boolean(_)) | (Shape::Boolean(_), Shape::Boolean(_))
@ -775,7 +777,7 @@ fn normalize_path(p: PathBuf) -> PathBuf {
return normalized; return normalized;
} }
impl walk::Walker for Rewriter { impl Walker for Rewriter {
fn walk_statement_list(&mut self, stmts: Vec<&mut Statement>) { fn walk_statement_list(&mut self, stmts: Vec<&mut Statement>) {
for v in stmts { for v in stmts {
self.walk_statement(v); self.walk_statement(v);
@ -1046,12 +1048,26 @@ impl Expression {
CastType::Float => Shape::Float(PositionedItem::new(0.0, def.pos.clone())), CastType::Float => Shape::Float(PositionedItem::new(0.0, def.pos.clone())),
CastType::Bool => Shape::Boolean(PositionedItem::new(true, def.pos.clone())), CastType::Bool => Shape::Boolean(PositionedItem::new(true, def.pos.clone())),
}, },
Expression::Import(def) => { Expression::Import(def) => Shape::Symbol(PositionedItem::new(
// FIXME(jwall): What should this do? def.path.fragment.clone(),
Shape::Symbol(PositionedItem::new( def.path.pos.clone(),
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)), _ => Shape::Empty(Position::new(0, 0, 0)),
}; };

View File

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

View File

@ -154,6 +154,10 @@ fn derive_shape_expressions() {
"bool(\"true\");", "bool(\"true\");",
Shape::Boolean(PositionedItem::new(true, Position::new(0, 0, 0))), 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 { for (expr, shape) in expr_cases {

View File

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

View File

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

View File

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