diff --git a/nac3core/src/expression.rs b/nac3core/src/expression.rs new file mode 100644 index 00000000..2329d943 --- /dev/null +++ b/nac3core/src/expression.rs @@ -0,0 +1,66 @@ +use crate::inference::resolve_call; +use crate::primitives::*; +use crate::typedef::{GlobalContext, Type, Type::*}; +use rustpython_parser::ast::{Expression, ExpressionType}; +use std::collections::HashMap; +use std::convert::TryFrom; +use std::rc::Rc; + +type SymTable<'a> = HashMap<&'a str, Rc>; +type ParserResult = Result, String>; + +pub fn parse_expr(ctx: &GlobalContext, sym_table: &SymTable, expr: &Expression) -> ParserResult { + Err("not supported".to_string()) +} + +fn parse_constant( + ctx: &GlobalContext, + sym_table: &SymTable, + value: &rustpython_parser::ast::Number, +) -> ParserResult { + use rustpython_parser::ast::Number; + match value { + Number::Integer { value } => { + if i32::try_from(&value).is_ok() { + Ok(PrimitiveType(INT32_TYPE).into()) + } else if i64::try_from(&value).is_ok() { + Ok(PrimitiveType(INT64_TYPE).into()) + } else { + Err("integer out of range".to_string()) + } + } + Number::Float { .. } => Ok(PrimitiveType(FLOAT_TYPE).into()), + _ => Err("not supported".to_string()), + } +} + +fn parse_identifier(ctx: &GlobalContext, sym_table: &SymTable, name: &str) -> ParserResult { + match sym_table.get(name) { + Some(v) => Ok(v.clone()), + None => Err("unbounded variable".to_string()), + } +} + +fn parse_list( + ctx: &GlobalContext, + sym_table: &SymTable, + elements: &[Expression], +) -> ParserResult { + if elements.len() == 0 { + return Ok(ParametricType(LIST_TYPE, vec![BotType.into()]).into()); + } + + let mut types = elements + .iter() + .map(|v| parse_expr(&ctx, sym_table, v)); + + let head = types.next().unwrap()?; + for v in types { + if v? != head { + return Err("inhomogeneous list is not allowed".to_string()); + } + } + Ok(ParametricType(LIST_TYPE, vec![head]).into()) +} + + diff --git a/nac3core/src/lib.rs b/nac3core/src/lib.rs index 761cc82e..785dfc07 100644 --- a/nac3core/src/lib.rs +++ b/nac3core/src/lib.rs @@ -5,6 +5,7 @@ extern crate rustpython_parser; pub mod inference; pub mod primitives; pub mod typedef; +pub mod expression; use std::error::Error; use std::fmt;