From bde52f7ad3c06e46c6457fc1102f0b9f7f04830f Mon Sep 17 00:00:00 2001 From: pca006132 Date: Mon, 4 Jan 2021 14:52:00 +0800 Subject: [PATCH] added primitives --- nac3core/src/lib.rs | 1 + nac3core/src/primitives.rs | 184 +++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 nac3core/src/primitives.rs diff --git a/nac3core/src/lib.rs b/nac3core/src/lib.rs index 4c939d3e..73495624 100644 --- a/nac3core/src/lib.rs +++ b/nac3core/src/lib.rs @@ -5,6 +5,7 @@ extern crate num_bigint; extern crate inkwell; extern crate rustpython_parser; +pub mod primitives; pub mod typedef; pub mod context; diff --git a/nac3core/src/primitives.rs b/nac3core/src/primitives.rs new file mode 100644 index 00000000..e7777491 --- /dev/null +++ b/nac3core/src/primitives.rs @@ -0,0 +1,184 @@ +use super::typedef::{TypeEnum::*, *}; +use crate::context::*; +use std::collections::HashMap; + +pub const TUPLE_TYPE: ParamId = ParamId(0); +pub const LIST_TYPE: ParamId = ParamId(1); + +pub const BOOL_TYPE: PrimitiveId = PrimitiveId(0); +pub const INT32_TYPE: PrimitiveId = PrimitiveId(1); +pub const INT64_TYPE: PrimitiveId = PrimitiveId(2); +pub const FLOAT_TYPE: PrimitiveId = PrimitiveId(3); + +fn impl_math(def: &mut TypeDef, ty: &Type) { + let result = Some(ty.clone()); + let fun = FnDef { + args: vec![ty.clone()], + result: result.clone(), + }; + def.methods.insert("__add__", fun.clone()); + def.methods.insert("__sub__", fun.clone()); + def.methods.insert("__mul__", fun.clone()); + def.methods.insert( + "__neg__", + FnDef { + args: vec![], + result, + }, + ); + def.methods.insert( + "__truediv__", + FnDef { + args: vec![ty.clone()], + result: Some(PrimitiveType(FLOAT_TYPE).into()), + }, + ); + def.methods.insert("__floordiv__", fun.clone()); + def.methods.insert("__mod__", fun.clone()); + def.methods.insert("__pow__", fun); +} + +fn impl_bits(def: &mut TypeDef, ty: &Type) { + let result = Some(ty.clone()); + let fun = FnDef { + args: vec![PrimitiveType(INT32_TYPE).into()], + result, + }; + + def.methods.insert("__lshift__", fun.clone()); + def.methods.insert("__rshift__", fun); + def.methods.insert( + "__xor__", + FnDef { + args: vec![ty.clone()], + result: Some(ty.clone()), + }, + ); +} + +fn impl_eq(def: &mut TypeDef, ty: &Type) { + let fun = FnDef { + args: vec![ty.clone()], + result: Some(PrimitiveType(BOOL_TYPE).into()), + }; + + def.methods.insert("__eq__", fun.clone()); + def.methods.insert("__ne__", fun); +} + +fn impl_order(def: &mut TypeDef, ty: &Type) { + let fun = FnDef { + args: vec![ty.clone()], + result: Some(PrimitiveType(BOOL_TYPE).into()), + }; + + def.methods.insert("__lt__", fun.clone()); + def.methods.insert("__gt__", fun.clone()); + def.methods.insert("__le__", fun.clone()); + def.methods.insert("__ge__", fun); +} + +pub fn basic_ctx() -> TopLevelContext<'static> { + let primitives = [ + TypeDef { + name: "bool", + fields: HashMap::new(), + methods: HashMap::new(), + }, + TypeDef { + name: "int32", + fields: HashMap::new(), + methods: HashMap::new(), + }, + TypeDef { + name: "int64", + fields: HashMap::new(), + methods: HashMap::new(), + }, + TypeDef { + name: "float", + fields: HashMap::new(), + methods: HashMap::new(), + }, + ] + .to_vec(); + let mut ctx = TopLevelContext::new(primitives); + + let b = ctx.get_primitive(BOOL_TYPE); + let b_def = ctx.get_primitive_def_mut(BOOL_TYPE); + impl_eq(b_def, &b); + let int32 = ctx.get_primitive(INT32_TYPE); + let int32_def = ctx.get_primitive_def_mut(INT32_TYPE); + impl_math(int32_def, &int32); + impl_bits(int32_def, &int32); + impl_order(int32_def, &int32); + impl_eq(int32_def, &int32); + let int64 = ctx.get_primitive(INT64_TYPE); + let int64_def = ctx.get_primitive_def_mut(INT64_TYPE); + impl_math(int64_def, &int64); + impl_bits(int64_def, &int64); + impl_order(int64_def, &int64); + impl_eq(int64_def, &int64); + let float = ctx.get_primitive(FLOAT_TYPE); + let float_def = ctx.get_primitive_def_mut(FLOAT_TYPE); + impl_math(float_def, &float); + impl_order(float_def, &float); + impl_eq(float_def, &float); + + let t = ctx.add_variable_private(VarDef { + name: "T", + bound: vec![], + }); + + ctx.add_parametric(ParametricDef { + base: TypeDef { + name: "tuple", + fields: HashMap::new(), + methods: HashMap::new(), + }, + // we have nothing for tuple, so no param def + params: vec![], + }); + + ctx.add_parametric(ParametricDef { + base: TypeDef { + name: "list", + fields: HashMap::new(), + methods: HashMap::new(), + }, + params: vec![t], + }); + + let i = ctx.add_variable_private(VarDef { + name: "I", + bound: vec![ + PrimitiveType(INT32_TYPE).into(), + PrimitiveType(INT64_TYPE).into(), + PrimitiveType(FLOAT_TYPE).into(), + ], + }); + let args = vec![TypeVariable(i).into()]; + ctx.add_fn( + "int32", + FnDef { + args: args.clone(), + result: Some(PrimitiveType(INT32_TYPE).into()), + }, + ); + ctx.add_fn( + "int64", + FnDef { + args: args.clone(), + result: Some(PrimitiveType(INT64_TYPE).into()), + }, + ); + ctx.add_fn( + "float", + FnDef { + args, + result: Some(PrimitiveType(FLOAT_TYPE).into()), + }, + ); + + ctx +}