jit: ops_ext delegation + M3 syntax scaffolding; unify BoxCall execution path
This commit is contained in:
59
src/grammar/engine.rs
Normal file
59
src/grammar/engine.rs
Normal file
@ -0,0 +1,59 @@
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use super::generated;
|
||||
|
||||
pub struct UnifiedGrammarEngine;
|
||||
|
||||
impl UnifiedGrammarEngine {
|
||||
pub fn load() -> Self { Self }
|
||||
pub fn is_keyword_str(&self, word: &str) -> Option<&'static str> {
|
||||
generated::lookup_keyword(word)
|
||||
}
|
||||
pub fn add_coercion_strategy(&self) -> &'static str {
|
||||
generated::OPERATORS_ADD_COERCION
|
||||
}
|
||||
pub fn add_rules(&self) -> &'static [(&'static str, &'static str, &'static str, &'static str)] {
|
||||
generated::OPERATORS_ADD_RULES
|
||||
}
|
||||
pub fn decide_add_result(&self, left_ty: &str, right_ty: &str) -> Option<(&'static str, &'static str)> {
|
||||
for (l, r, res, act) in self.add_rules() {
|
||||
if *l == left_ty && *r == right_ty { return Some((*res, *act)); }
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn sub_coercion_strategy(&self) -> &'static str { generated::OPERATORS_SUB_COERCION }
|
||||
pub fn sub_rules(&self) -> &'static [(&'static str, &'static str, &'static str, &'static str)] { generated::OPERATORS_SUB_RULES }
|
||||
pub fn decide_sub_result(&self, left_ty: &str, right_ty: &str) -> Option<(&'static str, &'static str)> {
|
||||
for (l, r, res, act) in self.sub_rules() { if *l == left_ty && *r == right_ty { return Some((*res, *act)); } }
|
||||
None
|
||||
}
|
||||
|
||||
pub fn mul_coercion_strategy(&self) -> &'static str { generated::OPERATORS_MUL_COERCION }
|
||||
pub fn mul_rules(&self) -> &'static [(&'static str, &'static str, &'static str, &'static str)] { generated::OPERATORS_MUL_RULES }
|
||||
pub fn decide_mul_result(&self, left_ty: &str, right_ty: &str) -> Option<(&'static str, &'static str)> {
|
||||
for (l, r, res, act) in self.mul_rules() { if *l == left_ty && *r == right_ty { return Some((*res, *act)); } }
|
||||
None
|
||||
}
|
||||
|
||||
pub fn div_coercion_strategy(&self) -> &'static str { generated::OPERATORS_DIV_COERCION }
|
||||
pub fn div_rules(&self) -> &'static [(&'static str, &'static str, &'static str, &'static str)] { generated::OPERATORS_DIV_RULES }
|
||||
pub fn decide_div_result(&self, left_ty: &str, right_ty: &str) -> Option<(&'static str, &'static str)> {
|
||||
for (l, r, res, act) in self.div_rules() { if *l == left_ty && *r == right_ty { return Some((*res, *act)); } }
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub static ENGINE: Lazy<UnifiedGrammarEngine> = Lazy::new(UnifiedGrammarEngine::load);
|
||||
|
||||
pub fn get() -> &'static UnifiedGrammarEngine { &ENGINE }
|
||||
|
||||
// --- Syntax rule helpers (generated-backed) ---
|
||||
impl UnifiedGrammarEngine {
|
||||
pub fn syntax_is_allowed_statement(&self, keyword: &str) -> bool {
|
||||
super::generated::SYNTAX_ALLOWED_STATEMENTS.iter().any(|k| *k == keyword)
|
||||
}
|
||||
pub fn syntax_is_allowed_binop(&self, op: &str) -> bool {
|
||||
super::generated::SYNTAX_ALLOWED_BINOPS.iter().any(|k| *k == op)
|
||||
}
|
||||
}
|
||||
69
src/grammar/generated.rs
Normal file
69
src/grammar/generated.rs
Normal file
@ -0,0 +1,69 @@
|
||||
// Auto-generated from grammar/unified-grammar.toml
|
||||
pub static KEYWORDS: &[(&str, &str)] = &[
|
||||
("me", "ME"),
|
||||
("from", "FROM"),
|
||||
("loop", "LOOP"),
|
||||
];
|
||||
pub static OPERATORS_ADD_COERCION: &str = "string_priority";
|
||||
pub static OPERATORS_SUB_COERCION: &str = "numeric_only";
|
||||
pub static OPERATORS_MUL_COERCION: &str = "numeric_only";
|
||||
pub static OPERATORS_DIV_COERCION: &str = "numeric_only";
|
||||
pub static OPERATORS_ADD_RULES: &[(&str, &str, &str, &str)] = &[
|
||||
("String", "String", "String", "concat"),
|
||||
("String", "Integer", "String", "concat"),
|
||||
("Integer", "String", "String", "concat"),
|
||||
("String", "Bool", "String", "concat"),
|
||||
("Bool", "String", "String", "concat"),
|
||||
("String", "Other", "String", "concat"),
|
||||
("Other", "String", "String", "concat"),
|
||||
("Integer", "Integer", "Integer", "add_i64"),
|
||||
("Float", "Float", "Float", "add_f64"),
|
||||
];
|
||||
pub static OPERATORS_SUB_RULES: &[(&str, &str, &str, &str)] = &[
|
||||
("Integer", "Integer", "Integer", "sub_i64"),
|
||||
("Float", "Float", "Float", "sub_f64"),
|
||||
];
|
||||
pub static OPERATORS_MUL_RULES: &[(&str, &str, &str, &str)] = &[
|
||||
("Integer", "Integer", "Integer", "mul_i64"),
|
||||
("Float", "Float", "Float", "mul_f64"),
|
||||
];
|
||||
pub static OPERATORS_DIV_RULES: &[(&str, &str, &str, &str)] = &[
|
||||
("Integer", "Integer", "Integer", "div_i64"),
|
||||
("Float", "Float", "Float", "div_f64"),
|
||||
];
|
||||
pub fn lookup_keyword(word: &str) -> Option<&'static str> {
|
||||
for (k, t) in KEYWORDS {
|
||||
if *k == word { return Some(*t); }
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub static SYNTAX_ALLOWED_STATEMENTS: &[&str] = &[
|
||||
"box",
|
||||
"global",
|
||||
"function",
|
||||
"static",
|
||||
"if",
|
||||
"loop",
|
||||
"break",
|
||||
"return",
|
||||
"print",
|
||||
"nowait",
|
||||
"include",
|
||||
"local",
|
||||
"outbox",
|
||||
"try",
|
||||
"throw",
|
||||
"using",
|
||||
"from",
|
||||
];
|
||||
pub static SYNTAX_ALLOWED_BINOPS: &[&str] = &[
|
||||
"add",
|
||||
"sub",
|
||||
"mul",
|
||||
"div",
|
||||
"and",
|
||||
"or",
|
||||
"eq",
|
||||
"ne",
|
||||
];
|
||||
6
src/grammar/mod.rs
Normal file
6
src/grammar/mod.rs
Normal file
@ -0,0 +1,6 @@
|
||||
pub mod engine;
|
||||
// Generated tables from grammar/unified-grammar.toml
|
||||
#[path = "generated.rs"]
|
||||
mod generated;
|
||||
pub use generated::*;
|
||||
|
||||
Reference in New Issue
Block a user