diff --git a/src/protocol/parser/mod.rs b/src/protocol/parser/mod.rs index acd963e0feb294e292cbf95b758b73d0c18a421c..2a7a85099282418fbec1e42f3a71425cfc766919 100644 --- a/src/protocol/parser/mod.rs +++ b/src/protocol/parser/mod.rs @@ -25,12 +25,13 @@ use pass_typing::{PassTyping, ResolveQueue}; use pass_rewriting::PassRewriting; use pass_stack_size::PassStackSize; use symbol_table::*; -use type_table::TypeTable; +use type_table::*; use crate::protocol::ast::*; use crate::protocol::input_source::*; use crate::protocol::ast_printer::ASTWriter; +use crate::protocol::parser::type_table::PolymorphicVariable; #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum ModuleCompilationPhase { @@ -57,16 +58,50 @@ pub struct Module { pub phase: ModuleCompilationPhase, } -// TODO: This is kind of wrong. Because when we're producing bytecode we would -// like the bytecode itself to not have the notion of the size of a pointer -// type. But until I figure out what we do want I'll just set everything -// to a 64-bit architecture. pub struct TargetArch { - pub array_size_alignment: (usize, usize), - pub slice_size_alignment: (usize, usize), - pub string_size_alignment: (usize, usize), - pub port_size_alignment: (usize, usize), - pub pointer_size_alignment: (usize, usize), + pub void_type_id: TypeId, + pub message_type_id: TypeId, + pub bool_type_id: TypeId, + pub uint8_type_id: TypeId, + pub uint16_type_id: TypeId, + pub uint32_type_id: TypeId, + pub uint64_type_id: TypeId, + pub sint8_type_id: TypeId, + pub sint16_type_id: TypeId, + pub sint32_type_id: TypeId, + pub sint64_type_id: TypeId, + pub char_type_id: TypeId, + pub string_type_id: TypeId, + pub array_type_id: TypeId, + pub slice_type_id: TypeId, + pub input_type_id: TypeId, + pub output_type_id: TypeId, + pub pointer_type_id: TypeId, +} + +impl TargetArch { + fn new() -> Self { + return Self{ + void_type_id: TypeId::new_invalid(), + bool_type_id: TypeId::new_invalid(), + message_type_id: TypeId::new_invalid(), + uint8_type_id: TypeId::new_invalid(), + uint16_type_id: TypeId::new_invalid(), + uint32_type_id: TypeId::new_invalid(), + uint64_type_id: TypeId::new_invalid(), + sint8_type_id: TypeId::new_invalid(), + sint16_type_id: TypeId::new_invalid(), + sint32_type_id: TypeId::new_invalid(), + sint64_type_id: TypeId::new_invalid(), + char_type_id: TypeId::new_invalid(), + string_type_id: TypeId::new_invalid(), + array_type_id: TypeId::new_invalid(), + slice_type_id: TypeId::new_invalid(), + input_type_id: TypeId::new_invalid(), + output_type_id: TypeId::new_invalid(), + pointer_type_id: TypeId::new_invalid(), + } + } } pub struct PassCtx<'a> { @@ -115,17 +150,33 @@ impl Parser { pass_rewriting: PassRewriting::new(), pass_stack_size: PassStackSize::new(), write_ast_to: None, - arch: TargetArch { - array_size_alignment: (3*8, 8), // pointer, length, capacity - slice_size_alignment: (2*8, 8), // pointer, length - string_size_alignment: (3*8, 8), // pointer, length, capacity - port_size_alignment: (3*4, 4), // two u32s: connector + port ID - pointer_size_alignment: (8, 8), - } + arch: TargetArch::new(), }; parser.symbol_table.insert_scope(None, SymbolScope::Global); + // Insert builtin types + // TODO: At some point use correct values for size/alignment + parser.arch.void_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::Void], false, 0, 1); + parser.arch.message_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::Message], false, 24, 8); + parser.arch.bool_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::Bool], false, 1, 1); + parser.arch.uint8_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::UInt8], false, 1, 1); + parser.arch.uint16_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::UInt16], false, 2, 2); + parser.arch.uint32_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::UInt32], false, 4, 4); + parser.arch.uint64_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::UInt64], false, 8, 8); + parser.arch.sint8_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::SInt8], false, 1, 1); + parser.arch.sint16_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::SInt16], false, 2, 2); + parser.arch.sint32_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::SInt32], false, 4, 4); + parser.arch.sint64_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::SInt64], false, 8, 8); + parser.arch.char_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::Character], false, 4, 4); + parser.arch.string_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::String], false, 24, 8); + parser.arch.array_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::Array, ConcreteTypePart::Void], true, 24, 8); + parser.arch.slice_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::Slice, ConcreteTypePart::Void], true, 16, 4); + parser.arch.input_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::Input, ConcreteTypePart::Void], true, 8, 8); + parser.arch.output_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::Output, ConcreteTypePart::Void], true, 8, 8); + parser.arch.pointer_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::Pointer, ConcreteTypePart::Void], true, 8, 8); + + // Insert builtin functions fn quick_type(variants: &[ParserTypeVariant]) -> ParserType { let mut t = ParserType{ elements: Vec::with_capacity(variants.len()), full_span: InputSpan::new() }; for variant in variants { @@ -288,10 +339,26 @@ impl Parser { } } +fn insert_builtin_type(type_table: &mut TypeTable, parts: Vec, has_poly_var: bool, size: usize, alignment: usize) -> TypeId { + const POLY_VARS: [PolymorphicVariable; 1] = [PolymorphicVariable{ + identifier: Identifier::new_empty(InputSpan::new()), + is_in_use: false, + }]; + + let concrete_type = ConcreteType{ parts }; + let poly_var = if has_poly_var { + POLY_VARS.as_slice() + } else { + &[] + }; + + return type_table.add_builtin_type(concrete_type, poly_var, size, alignment); +} + // Note: args and return type need to be a function because we need to know the function ID. fn insert_builtin_function (Vec<(&'static str, ParserType)>, ParserType)> ( - p: &mut Parser, func_name: &str, polymorphic: &[&str], arg_and_return_fn: T) { - + p: &mut Parser, func_name: &str, polymorphic: &[&str], arg_and_return_fn: T +) { let mut poly_vars = Vec::with_capacity(polymorphic.len()); for poly_var in polymorphic { poly_vars.push(Identifier{ span: InputSpan::new(), value: p.string_pool.intern(poly_var.as_bytes()) });