diff --git a/src/cst/always_statement.rs b/src/cst/always_statement.rs index ec0527d..0050799 100644 --- a/src/cst/always_statement.rs +++ b/src/cst/always_statement.rs @@ -16,6 +16,8 @@ impl AlwaysStatement { match json["children"][0]["tag"].as_str() { Some(Tag::ALWAYS) => { + assert_eq!(context.events.len(), 0); + let json_statement = Tools::match_tags( vec![json], vec![ @@ -24,7 +26,9 @@ impl AlwaysStatement { ], ); assert_eq!(json_statement.len(), 1); - Self::gen_always(json_statement[0], context, &mut None); + Self::gen_always(json_statement[0], context); + + context.events.clear(); } Some(Tag::ALWAYS_COMB) => { error!("TODO: implmenent '{}'", Tag::ALWAYS_COMB); @@ -81,9 +85,11 @@ impl AlwaysStatement { proc_signature, ); let mut proc_builder = UnitBuilder::new_anonymous(&mut proc_data); + let mut arg_to_raw_name = HashMap::new(); for (arg, name) in arg_name { let value = proc_builder.arg_value(arg); proc_builder.set_name(value, name.to_string()); + arg_to_raw_name.insert(value, name.to_string()); } // hack @@ -93,6 +99,8 @@ impl AlwaysStatement { // once again match json["children"][0]["tag"].as_str() { Some(Tag::ALWAYS) => { + assert_eq!(context.events.len(), 0); + let json_statement = Tools::match_tags( vec![json], vec![ @@ -101,7 +109,33 @@ impl AlwaysStatement { ], ); assert_eq!(json_statement.len(), 1); - Self::gen_always(json_statement[0], context, &mut Some(proc_builder)); + Self::gen_always(json_statement[0], context); + + // codegen internal + { + let block_0 = proc_builder.named_block("0"); + let block_init = proc_builder.named_block("init"); + let block_check = proc_builder.named_block("check"); + + proc_builder.append_to(block_0); + let outputs: Vec = proc_builder.unit().output_args().collect(); + outputs.iter().for_each(|x| { + let output_prb = proc_builder.ins().prb(*x); + proc_builder.ins().suffix(*x, "shadow").var(output_prb); + }); + proc_builder.ins().br(block_init); + + proc_builder.append_to(block_init); + let inputs: Vec = proc_builder.unit().input_args().collect(); + let events: Vec = inputs + .iter() + .filter(|x| context.events.contains(&arg_to_raw_name[&x])) + .map(|x| proc_builder.ins().suffix(*x, "prb").prb(*x)) + .collect(); + proc_builder.ins().wait(block_check, events); + } + + context.events.clear(); } Some(Tag::ALWAYS_COMB) => { error!("TODO: implmenent '{}'", Tag::ALWAYS_COMB); @@ -123,11 +157,7 @@ impl AlwaysStatement { proc_id } - fn gen_always( - json: &JsonValue, - context: &mut ModuleContext, - unit_builder: &mut Option, - ) { + fn gen_always(json: &JsonValue, context: &mut ModuleContext) { assert_eq!(json["tag"], Tag::PROCEDURAL_TIMING_CONTROL_STATEMENT); let (json_event_control, json_statement) = { @@ -137,22 +167,6 @@ impl AlwaysStatement { (&json_children[0], &json_children[1]) }; - match unit_builder { - Some(builder) => { - let block_0 = builder.named_block("0"); - let block_init = builder.named_block("init"); - let _block_check = builder.named_block("check"); - builder.append_to(block_0); - let outputs: Vec = builder.unit().output_args().collect(); - for output in outputs { - let output_prb = builder.ins().prb(output); - builder.ins().suffix(output, "shadow").var(output_prb); - } - builder.ins().br(block_init); - } - None => {} - }; - let json_event_expression_list = Tools::match_tags( vec![json_event_control], vec![ diff --git a/src/cst/context.rs b/src/cst/context.rs index 0ceec78..a7c007d 100644 --- a/src/cst/context.rs +++ b/src/cst/context.rs @@ -9,6 +9,8 @@ pub struct ModuleContext { pub symbol: LinkedHashMap, pub lvalues: LinkedHashSet, pub rvalues: LinkedHashSet, + pub tags: Vec<&'static str>, + pub events: LinkedHashSet, } pub struct SymbolInfo { @@ -45,6 +47,8 @@ impl ModuleContext { symbol: LinkedHashMap::new(), lvalues: LinkedHashSet::new(), rvalues: LinkedHashSet::new(), + tags: Vec::new(), + events: LinkedHashSet::new(), } } } diff --git a/src/cst/event_expression_list.rs b/src/cst/event_expression_list.rs index 6e80548..a1d0234 100644 --- a/src/cst/event_expression_list.rs +++ b/src/cst/event_expression_list.rs @@ -8,6 +8,8 @@ pub struct EventExpressionList {} impl EventExpressionList { pub fn codegen(json: &JsonValue, context: &mut ModuleContext) { + context.tags.push(Tag::EVENT_EXPRESSION_LIST); + let json_expressions = Tools::match_tags( vec![json], vec![Tag::EVENT_EXPRESSION_LIST, Tag::EVENT_EXPRESSION], @@ -26,5 +28,7 @@ impl EventExpressionList { } warn!("TODO: finish codegen()"); + + context.tags.pop(); } } diff --git a/src/cst/expression.rs b/src/cst/expression.rs index 5b2c26c..1cfb601 100644 --- a/src/cst/expression.rs +++ b/src/cst/expression.rs @@ -33,8 +33,15 @@ impl Expression { ); assert_eq!(json_symbol_identifier.len(), 1); - let symbol = json_symbol_identifier[0]["text"].to_string(); - context.rvalues.insert(symbol); + let symbol = &json_symbol_identifier[0]["text"]; + context.rvalues.insert(symbol.to_string()); + + match context.tags.last() { + Some(&Tag::EVENT_EXPRESSION_LIST) => { + context.events.insert(symbol.to_string()); + } + _ => {} + } warn!("TODO: case '{}'", Tag::REFERENCE_CALL_BASE); }