Changeset - 95e019faaf52
[Not reviewed]
0 8 1
mh - 3 years ago 2022-03-29 18:18:12
contact@maxhenger.nl
Getting builtin component instantiation to compile
9 files changed with 42 insertions and 14 deletions:
0 comments (0 inline, 0 general)
src/protocol/ast.rs
Show inline comments
 
@@ -1835,34 +1835,37 @@ pub struct CallExpression {
 
    // Typing
 
    pub type_index: i32,
 
}
 

	
 
#[derive(Debug, Clone, PartialEq, Eq)]
 
pub enum Method {
 
    // Builtin, accessible by programmer
 
    // Builtin function, accessible by programmer
 
    Get,
 
    Put,
 
    Fires,
 
    Create,
 
    Length,
 
    Assert,
 
    Print,
 
    // Builtin, not accessible by programmer
 
    // Builtin function, not accessible by programmer
 
    SelectStart, // SelectStart(total_num_cases, total_num_ports)
 
    SelectRegisterCasePort, // SelectRegisterCasePort(case_index, port_index, port_id)
 
    SelectWait, // SelectWait() -> u32
 
    // Builtin component,
 
    ComponentRandomU32,
 
    // User-defined
 
    UserFunction,
 
    UserComponent,
 
}
 

	
 
impl Method {
 
    pub(crate) fn is_public_builtin(&self) -> bool {
 
        use Method::*;
 
        match self {
 
            Get | Put | Fires | Create | Length | Assert | Print => true,
 
            ComponentRandomU32 => true,
 
            _ => false,
 
        }
 
    }
 

	
 
    pub(crate) fn is_user_defined(&self) -> bool {
 
        use Method::*;
src/protocol/eval/executor.rs
Show inline comments
 
@@ -752,17 +752,21 @@ impl Prompt {
 
                                        None => {
 
                                            cur_frame.expr_stack.push_back(ExprInstruction::EvalExpr(expr.this.upcast()));
 
                                            return Ok(EvalContinuation::SelectWait)
 
                                        },
 
                                    }
 
                                },
 
                                Method::ComponentRandomU32 => {
 
                                    debug_assert_eq!(heap[expr.procedure].parameters.len(), cur_frame.expr_values.len());
 
                                    debug_assert_eq!(heap[cur_frame.position].as_new().expression, expr.this);
 
                                },
 
                                Method::UserComponent => {
 
                                    // This is actually handled by the evaluation
 
                                    // of the statement.
 
                                    debug_assert_eq!(heap[expr.procedure].parameters.len(), cur_frame.expr_values.len());
 
                                    debug_assert_eq!(heap[cur_frame.position].as_new().expression, expr.this)
 
                                    debug_assert_eq!(heap[cur_frame.position].as_new().expression, expr.this);
 
                                },
 
                                Method::UserFunction => {
 
                                    // Push a new frame. Note that all expressions have
 
                                    // been pushed to the front, so they're in the order
 
                                    // of the definition.
 
                                    let num_args = expr.arguments.len();
src/protocol/parser/mod.rs
Show inline comments
 
@@ -293,14 +293,15 @@ impl Parser {
 
    /// Tries to find the standard library and add the files for parsing.
 
    fn feed_standard_library(&mut self) -> Result<(), String> {
 
        use std::env;
 
        use std::path::{Path, PathBuf};
 
        use std::fs;
 

	
 
        const FILES: [&'static str; 1] = [
 
        const FILES: [&'static str; 2] = [
 
            "std.global.pdl",
 
            "std.random.pdl",
 
        ];
 

	
 
        // Determine base directory
 
        let (base_path, from_env) = if let Ok(path) = env::var(REOWOLF_PATH_ENV) {
 
            // Path variable is set
 
            (path, true)
 
@@ -321,12 +322,13 @@ impl Parser {
 
        // way to do this in the future (i.e. a "std" package, containing all
 
        // of the modules)
 
        let mut file_path = PathBuf::new();
 
        let mut first_file = true;
 

	
 
        for file in FILES {
 
            file_path.clear();
 
            file_path.push(path);
 
            file_path.push(file);
 

	
 
            let source = fs::read(file_path.as_path());
 
            if let Err(err) = source {
 
                return Err(format!(
src/protocol/parser/pass_definitions.rs
Show inline comments
 
@@ -373,12 +373,13 @@ impl PassDefinitions {
 
                ("std.global", "put") => ProcedureSource::FuncPut,
 
                ("std.global", "fires") => ProcedureSource::FuncFires,
 
                ("std.global", "create") => ProcedureSource::FuncCreate,
 
                ("std.global", "length") => ProcedureSource::FuncLength,
 
                ("std.global", "assert") => ProcedureSource::FuncAssert,
 
                ("std.global", "print") => ProcedureSource::FuncPrint,
 
                ("std.random", "random_u32") => ProcedureSource::CompRandomU32,
 
                _ => panic!(
 
                    "compiler error: unknown builtin procedure '{}' in module '{}'",
 
                    procedure_name, module_name
 
                ),
 
            };
 

	
 
@@ -822,16 +823,14 @@ impl PassDefinitions {
 
        let mut valid = false;
 

	
 
        let mut call_id = CallExpressionId::new_invalid();
 
        if let Expression::Call(expression) = expression {
 
            // Allow both components and functions, as it makes more sense to
 
            // check their correct use in the validation and linking pass
 
            if expression.method == Method::UserComponent || expression.method == Method::UserFunction {
 
                call_id = expression.this;
 
                valid = true;
 
            }
 
            call_id = expression.this;
 
            valid = true;
 
        }
 

	
 
        if !valid {
 
            return Err(ParseError::new_error_str_at_span(
 
                &module.source, InputSpan::from_positions(start_pos, iter.last_valid_pos()), "expected a call expression"
 
            ));
 
@@ -1655,13 +1654,14 @@ impl PassDefinitions {
 
                                    ProcedureSource::FuncPut => Method::Put,
 
                                    ProcedureSource::FuncFires => Method::Fires,
 
                                    ProcedureSource::FuncCreate => Method::Create,
 
                                    ProcedureSource::FuncLength => Method::Length,
 
                                    ProcedureSource::FuncAssert => Method::Assert,
 
                                    ProcedureSource::FuncPrint => Method::Print,
 
                                    _ => todo!("other proc sources")
 
                                    ProcedureSource::CompRandomU32 => Method::ComponentRandomU32,
 
                                    _ => todo!("other procedure sources"),
 
                                };
 

	
 
                                // Function call: consume the arguments
 
                                let func_span = parser_type.full_span;
 
                                let mut full_span = func_span;
 
                                let arguments = self.consume_expression_list(
src/protocol/parser/pass_validation_linking.rs
Show inline comments
 
@@ -1157,12 +1157,15 @@ impl Visitor for PassValidationLinking {
 
                }
 
            },
 
            Method::Print => {},
 
            Method::SelectStart
 
            | Method::SelectRegisterCasePort
 
            | Method::SelectWait => unreachable!(), // not usable by programmer directly
 
            Method::ComponentRandomU32 => {
 
                expecting_wrapping_new_stmt = true;
 
            },
 
            Method::UserFunction => {}
 
            Method::UserComponent => {
 
                expecting_wrapping_new_stmt = true;
 
            },
 
        }
 

	
src/protocol/parser/type_table.rs
Show inline comments
 
@@ -2042,12 +2042,13 @@ impl TypeTable {
 
                mono_type.heap_alignment = max_alignment;
 
            }
 
        }
 

	
 
        // And now, we're actually, properly, done
 
        self.encountered_types.clear();
 
        self.size_alignment_stack.clear();
 
    }
 

	
 
    /// Attempts to compute size/alignment for the provided type. Note that this
 
    /// is called *after* type loops have been succesfully resolved. Hence we
 
    /// may assume that all monomorph entries exist, but we may not assume that
 
    /// those entries already have their size/alignment computed.
src/runtime2/tests/mod.rs
Show inline comments
 
@@ -216,7 +216,24 @@ fn test_empty_select() {
 
            index += 1;
 
        }
 
    }
 
    ").expect("compilation");
 
    let rt = Runtime::new(3, false, pd);
 
    create_component(&rt, "", "constructor", no_args());
 
}
 

	
 
#[test]
 
fn test_random_u32_temporary_thingo() {
 
    let pd = ProtocolDescription::parse(b"
 
    primitive random_taker(in<u32> generator) {
 
        sync {
 
            auto a = get(generator);
 
        }
 
    }
 

	
 
    composite constructor() {
 
        channel tx -> rx;
 
        new random_u32(tx, 1, 100);
 
        new random_taker(rx);
 
    }
 
    ").expect("compilation");
 
}
 
\ No newline at end of file
std/std.global.pdl
Show inline comments
 
#module std.global
 

	
 
// Note: parsing of token ranges and pragma needs to change. For now we insert
 
// spaces to work with the current system. Needs to be a system where the
 
// pragmas, "func" keywords (and similar keywords) indicate initial points to
 
// start parsing.
 

	
 
func get<T>(in<T> input) -> T { #builtin }
 
func put<T>(out<T> output, T value) -> #type_void { #builtin }
 
func fires<T>(#type_portlike<T> port) -> bool { #builtin }
 
func create<T>(#type_integerlike len) -> T[] { #builtin }
 
func length<T>(#type_arraylike<T> array) -> u32 { #builtin }
 
func assert(bool condition) -> #type_void { #builtin }
std/std.random.pdl
Show inline comments
 
new file 100644
 
#module std.random
 

	
 
primitive random_u32(out<u32> generator, u32 min, u32 max) { #builtin }
0 comments (0 inline, 0 general)