Support unary negation and "kParameterAssignList"

This commit is contained in:
Guojie Luo 2023-04-24 05:18:14 +00:00
parent 0030a144ef
commit 54d6ffda3c
3 changed files with 49 additions and 26 deletions

View File

@ -23,7 +23,7 @@ impl Expression {
match json["tag"].as_str() { match json["tag"].as_str() {
Some(Tag::EXPRESSION) => { Some(Tag::EXPRESSION) => {
let json_expr = &json["children"]; let json_expr = &json["children"];
assert_eq!(json_expr.len(), 1); assert_eq!(json_expr.len(), 1, "{}", json);
Self::codegen(&json_expr[0], context) Self::codegen(&json_expr[0], context)
} }
Some(Tag::PAREN_GROUP) => { Some(Tag::PAREN_GROUP) => {
@ -321,6 +321,10 @@ impl Expression {
assert_eq!(bits.len(), 1); assert_eq!(bits.len(), 1);
Some(*bits[0]) Some(*bits[0])
} }
Some(Tag::NEGATION) => {
let value = builder.ins().neg(expr.unwrap());
Some(value)
}
_ => panic!("unknown error at CST node '{}'", json), _ => panic!("unknown error at CST node '{}'", json),
} }
} else { } else {

View File

@ -4,7 +4,7 @@ use crate::{
}; };
use json::JsonValue; use json::JsonValue;
use llhd::value::IntValue; use llhd::value::IntValue;
use std::collections::HashMap; use std::{collections::HashMap, iter::zip};
#[allow(unused_imports)] #[allow(unused_imports)]
use log::{debug, error, info, trace, warn}; use log::{debug, error, info, trace, warn};
@ -452,13 +452,28 @@ impl<'a> SymbolDeclaration {
Tag::PARAM_TYPE, Tag::PARAM_TYPE,
Tag::SYMBOL_IDENTIFIER, Tag::SYMBOL_IDENTIFIER,
], ],
vec![
Tag::PARAM_DECLARATION,
Tag::PARAMETER_ASSIGN_LIST,
Tag::PARAMETER_ASSIGN,
Tag::SYMBOL_IDENTIFIER,
],
]; ];
let num_path = [ let num_paths = [
Tag::PARAM_DECLARATION, vec![
Tag::TRAILING_ASSIGN, Tag::PARAM_DECLARATION,
Tag::EXPRESSION, Tag::TRAILING_ASSIGN,
Tag::NUMBER, 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()) let json_params: Vec<&JsonValue> = Tools::match_tags(vec![json], base_path.to_vec())
@ -468,24 +483,25 @@ impl<'a> SymbolDeclaration {
.collect(); .collect();
for json in json_params { for json in json_params {
let json_name = { let json_names: Vec<_> = name_paths
let json_names: Vec<_> = name_paths .iter()
.iter() .flat_map(|x| Tools::match_tags(vec![json], x.to_vec()))
.flat_map(|x| Tools::match_tags(vec![json], x.to_vec())) .collect();
.collect(); let json_nums: Vec<_> = num_paths
assert_eq!(json_names.len(), 1, "{}", json); .iter()
json_names[0] .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()); for (json_name, json_num) in zip(json_names, json_nums) {
assert_eq!(json_num.len(), 1); let num = Number::parse(json_num);
let v = Number::parse(json_num[0]); let name = json_name["text"].to_string();
let name = json_name["text"].to_string(); let symbol = SymbolInfo::new(SymbolKind::Param, num, json_name);
let symbol = SymbolInfo::new(SymbolKind::Param, v, json_name); trace!("found {} {}", SymbolKind::Param, 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()); let json_num = Tools::match_tags(vec![json], num_path.to_vec());
assert_eq!(json_num.len(), 1); 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 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); trace!("found {} {}", SymbolKind::Param, name);
context.symbol.insert(name, symbol); context.symbol.insert(name, symbol);
@ -594,10 +610,10 @@ impl<'a> SymbolDeclaration {
let json_num = Tools::match_tags(vec![json], num_path.to_vec()); let json_num = Tools::match_tags(vec![json], num_path.to_vec());
assert_eq!(json_num.len(), 1); 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 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); trace!("found {} {}", SymbolKind::Param, name);
context.symbol.insert(name, symbol); context.symbol.insert(name, symbol);

View File

@ -43,6 +43,8 @@ impl Tag {
pub const PARAM_DECLARATION: &'static str = "kParamDeclaration"; pub const PARAM_DECLARATION: &'static str = "kParamDeclaration";
pub const PARAM_TYPE: &'static str = "kParamType"; pub const PARAM_TYPE: &'static str = "kParamType";
pub const TRAILING_ASSIGN: &'static str = "kTrailingAssign"; 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_DECLARATION: &'static str = "kFormalParameterListDeclaration";
pub const FORMAL_PARAMETER_LIST: &'static str = "kFormalParameterList"; pub const FORMAL_PARAMETER_LIST: &'static str = "kFormalParameterList";
@ -133,6 +135,7 @@ impl Tag {
pub const LESS_THAN: &'static str = "<"; pub const LESS_THAN: &'static str = "<";
pub const GREATER_THAN: &'static str = ">"; pub const GREATER_THAN: &'static str = ">";
pub const NEGATION: &'static str = "-";
pub const LOGICAL_NOT: &'static str = "!"; pub const LOGICAL_NOT: &'static str = "!";
pub const BITWISE_NOT: &'static str = "~"; pub const BITWISE_NOT: &'static str = "~";
pub const XOR_REDUCE: &'static str = "^"; pub const XOR_REDUCE: &'static str = "^";