From 54d6ffda3cc246fc12cbdc4627ea4a48e8693b8a Mon Sep 17 00:00:00 2001 From: Guojie Luo Date: Mon, 24 Apr 2023 05:18:14 +0000 Subject: [PATCH] Support unary negation and "kParameterAssignList" --- src/cst/expression.rs | 6 +++- src/cst/symbol_declaration.rs | 66 ++++++++++++++++++++++------------- src/cst/tags.rs | 3 ++ 3 files changed, 49 insertions(+), 26 deletions(-) diff --git a/src/cst/expression.rs b/src/cst/expression.rs index 083144b..2fefaa1 100644 --- a/src/cst/expression.rs +++ b/src/cst/expression.rs @@ -23,7 +23,7 @@ impl Expression { match json["tag"].as_str() { Some(Tag::EXPRESSION) => { let json_expr = &json["children"]; - assert_eq!(json_expr.len(), 1); + assert_eq!(json_expr.len(), 1, "{}", json); Self::codegen(&json_expr[0], context) } Some(Tag::PAREN_GROUP) => { @@ -321,6 +321,10 @@ impl Expression { assert_eq!(bits.len(), 1); Some(*bits[0]) } + Some(Tag::NEGATION) => { + let value = builder.ins().neg(expr.unwrap()); + Some(value) + } _ => panic!("unknown error at CST node '{}'", json), } } else { diff --git a/src/cst/symbol_declaration.rs b/src/cst/symbol_declaration.rs index 9f9d163..b580c01 100644 --- a/src/cst/symbol_declaration.rs +++ b/src/cst/symbol_declaration.rs @@ -4,7 +4,7 @@ use crate::{ }; use json::JsonValue; use llhd::value::IntValue; -use std::collections::HashMap; +use std::{collections::HashMap, iter::zip}; #[allow(unused_imports)] use log::{debug, error, info, trace, warn}; @@ -452,13 +452,28 @@ impl<'a> SymbolDeclaration { Tag::PARAM_TYPE, Tag::SYMBOL_IDENTIFIER, ], + vec![ + Tag::PARAM_DECLARATION, + Tag::PARAMETER_ASSIGN_LIST, + Tag::PARAMETER_ASSIGN, + Tag::SYMBOL_IDENTIFIER, + ], ]; - let num_path = [ - Tag::PARAM_DECLARATION, - Tag::TRAILING_ASSIGN, - Tag::EXPRESSION, - Tag::NUMBER, + let num_paths = [ + vec![ + Tag::PARAM_DECLARATION, + Tag::TRAILING_ASSIGN, + Tag::EXPRESSION, + Tag::NUMBER, + ], + vec![ + Tag::PARAM_DECLARATION, + Tag::PARAMETER_ASSIGN_LIST, + Tag::PARAMETER_ASSIGN, + Tag::EXPRESSION, + Tag::NUMBER, + ], ]; let json_params: Vec<&JsonValue> = Tools::match_tags(vec![json], base_path.to_vec()) @@ -468,24 +483,25 @@ impl<'a> SymbolDeclaration { .collect(); for json in json_params { - let json_name = { - let json_names: Vec<_> = name_paths - .iter() - .flat_map(|x| Tools::match_tags(vec![json], x.to_vec())) - .collect(); - assert_eq!(json_names.len(), 1, "{}", json); - json_names[0] - }; + let json_names: Vec<_> = name_paths + .iter() + .flat_map(|x| Tools::match_tags(vec![json], x.to_vec())) + .collect(); + let json_nums: Vec<_> = num_paths + .iter() + .flat_map(|x| Tools::match_tags(vec![json], x.to_vec())) + .collect(); + assert_eq!(json_names.len(), json_nums.len()); - let json_num = Tools::match_tags(vec![json], num_path.to_vec()); - assert_eq!(json_num.len(), 1); - let v = Number::parse(json_num[0]); + for (json_name, json_num) in zip(json_names, json_nums) { + let num = Number::parse(json_num); + let name = json_name["text"].to_string(); - let name = json_name["text"].to_string(); - let symbol = SymbolInfo::new(SymbolKind::Param, v, json_name); - trace!("found {} {}", SymbolKind::Param, name); + let symbol = SymbolInfo::new(SymbolKind::Param, num, json_name); + trace!("found {} {}", SymbolKind::Param, name); - context.symbol.insert(name, symbol); + context.symbol.insert(name, symbol); + } } } @@ -538,10 +554,10 @@ impl<'a> SymbolDeclaration { let json_num = Tools::match_tags(vec![json], num_path.to_vec()); assert_eq!(json_num.len(), 1); - let v = Number::parse(json_num[0]); + let num = Number::parse(json_num[0]); let name = json_name["text"].to_string(); - let symbol = SymbolInfo::new(SymbolKind::Param, v, json_name); + let symbol = SymbolInfo::new(SymbolKind::Param, num, json_name); trace!("found {} {}", SymbolKind::Param, name); context.symbol.insert(name, symbol); @@ -594,10 +610,10 @@ impl<'a> SymbolDeclaration { let json_num = Tools::match_tags(vec![json], num_path.to_vec()); assert_eq!(json_num.len(), 1); - let v = Number::parse(json_num[0]); + let num = Number::parse(json_num[0]); let name = json_name["text"].to_string(); - let symbol = SymbolInfo::new(SymbolKind::Param, v, json_name); + let symbol = SymbolInfo::new(SymbolKind::Param, num, json_name); trace!("found {} {}", SymbolKind::Param, name); context.symbol.insert(name, symbol); diff --git a/src/cst/tags.rs b/src/cst/tags.rs index 58ecaf1..6ce8f82 100644 --- a/src/cst/tags.rs +++ b/src/cst/tags.rs @@ -43,6 +43,8 @@ impl Tag { pub const PARAM_DECLARATION: &'static str = "kParamDeclaration"; pub const PARAM_TYPE: &'static str = "kParamType"; pub const TRAILING_ASSIGN: &'static str = "kTrailingAssign"; + pub const PARAMETER_ASSIGN_LIST: &'static str = "kParameterAssignList"; + pub const PARAMETER_ASSIGN: &'static str = "kParameterAssign"; pub const FORMAL_PARAMETER_LIST_DECLARATION: &'static str = "kFormalParameterListDeclaration"; pub const FORMAL_PARAMETER_LIST: &'static str = "kFormalParameterList"; @@ -133,6 +135,7 @@ impl Tag { pub const LESS_THAN: &'static str = "<"; pub const GREATER_THAN: &'static str = ">"; + pub const NEGATION: &'static str = "-"; pub const LOGICAL_NOT: &'static str = "!"; pub const BITWISE_NOT: &'static str = "~"; pub const XOR_REDUCE: &'static str = "^";