nomiscript/runtime/symbol/
builtins.rs1use crate::ast::{Expr, Fraction, LambdaParams};
6
7use super::entry::{Symbol, SymbolKind};
8use super::table::SymbolTable;
9
10impl SymbolTable {
11 pub fn register_builtins(&mut self) {
12 for op in super::builtins_generated::OPERATORS {
16 self.define(Symbol::new(*op, SymbolKind::Operator));
17 }
18 for form in super::builtins_generated::SPECIAL_FORMS {
19 self.define(Symbol::new(*form, SymbolKind::SpecialForm));
20 }
21 for native in super::builtins_generated::NATIVES {
22 self.define(Symbol::new(*native, SymbolKind::Native));
23 }
24
25 self.register_entity_constants();
26 self.register_entity_accessors();
27
28 self.add_map_family_macros();
29 }
30
31 fn register_entity_constants(&mut self) {
32 use scripting_format::{ContextType, EntityType};
33
34 let entity_types: &[(&str, EntityType)] = &[
35 ("+ENTITY-TRANSACTION+", EntityType::Transaction),
36 ("+ENTITY-SPLIT+", EntityType::Split),
37 ("+ENTITY-TAG+", EntityType::Tag),
38 ("+ENTITY-ACCOUNT+", EntityType::Account),
39 ("+ENTITY-COMMODITY+", EntityType::Commodity),
40 ];
41 for (name, ty) in entity_types {
42 self.define(
43 Symbol::new(*name, SymbolKind::Variable)
44 .with_value(Expr::Number(Fraction::from_integer(i64::from(*ty as u8)))),
45 );
46 }
47
48 let context_types: &[(&str, ContextType)] = &[
49 ("+CONTEXT-CREATE+", ContextType::EntityCreate),
50 ("+CONTEXT-UPDATE+", ContextType::EntityUpdate),
51 ("+CONTEXT-DELETE+", ContextType::EntityDelete),
52 ("+CONTEXT-BATCH+", ContextType::BatchProcess),
53 ];
54 for (name, ct) in context_types {
55 self.define(
56 Symbol::new(*name, SymbolKind::Variable)
57 .with_value(Expr::Number(Fraction::from_integer(i64::from(*ct as u8)))),
58 );
59 }
60 }
61
62 pub(super) fn register_entity_accessors(&mut self) {
63 let accessors = [
64 "ENTITY-COUNT",
65 "CONTEXT-TYPE",
66 "PRIMARY-ENTITY-TYPE",
67 "PRIMARY-ENTITY-IDX",
68 "ENTITY-TYPE",
69 "ENTITY-PARENT-IDX",
70 "TRANSACTION-SPLIT-COUNT",
71 "TRANSACTION-TAG-COUNT",
72 "TRANSACTION-IS-MULTI-CURRENCY",
73 "TRANSACTION-POST-DATE",
74 "TRANSACTION-ENTER-DATE",
75 "SPLIT-VALUE-NUM",
76 "SPLIT-VALUE-DENOM",
77 "SPLIT-VALUE",
78 "SPLIT-RECONCILE-STATE",
79 "SPLIT-RECONCILE-DATE",
80 "SPLIT-ACCOUNT-NAME",
81 "CREATE-TAG",
82 "TAG-NAME",
83 "TAG-VALUE",
84 "STRING=",
85 "DELETE-ENTITY",
86 "ACCOUNT-ID",
88 "ACCOUNT-NAME",
89 "ACCOUNT-PARENT",
90 "COMMODITY-ID",
91 "COMMODITY-SYMBOL",
92 "COMMODITY-NAME",
93 "TRANSACTION-ID",
94 "TRANSACTION-NOTE",
95 "SPLIT-ID",
96 "SPLIT-ACCOUNT-ID",
97 "SPLIT-COMMODITY-ID",
98 "SPLIT-AMOUNT",
99 "TAG-ENTITY-ID",
100 "TAG-ENTITY-NAME",
101 "TAG-ENTITY-VALUE",
102 "PRICE-ID",
103 "PRICE-COMMODITY-ID",
104 "PRICE-CURRENCY-ID",
105 "PRICE-VALUE",
106 "PRICE-DATE",
107 "SSH-KEY-ID",
108 "SSH-KEY-FINGERPRINT",
109 "SSH-KEY-NAME",
110 "NODE-ID",
111 "NODE-LABEL",
112 "NODE-DEPTH",
113 "NODE-AMOUNT",
114 "NODE-CHILDREN",
115 ];
116 for name in accessors {
117 self.define(Symbol::new(name, SymbolKind::Native));
118 }
119 }
120
121 fn add_map_family_macros(&mut self) {
122 let mapcar_params = LambdaParams {
123 required: vec!["func".to_string(), "list".to_string()],
124 optional: Vec::new(),
125 rest: Some("lists".to_string()),
126 key: Vec::new(),
127 aux: Vec::new(),
128 };
129 let mapcar_body = Expr::List(vec![
130 Expr::Symbol("APPLY".to_string()),
131 Expr::Quote(Box::new(Expr::Symbol("LIST".to_string()))),
132 Expr::Quote(Box::new(Expr::Symbol("MAP".to_string()))),
133 Expr::Symbol("func".to_string()),
134 Expr::Symbol("list".to_string()),
135 Expr::Symbol("lists".to_string()),
136 ]);
137 let mapcar_lambda = Expr::Lambda(mapcar_params, Box::new(mapcar_body));
138 self.define(Symbol::new("MAPCAR", SymbolKind::Macro).with_function(mapcar_lambda));
139
140 let mapc_params = LambdaParams::simple(vec!["func".to_string(), "list".to_string()]);
141 let mapc_body = Expr::List(vec![
142 Expr::Symbol("LIST".to_string()),
143 Expr::Quote(Box::new(Expr::Symbol("MAP".to_string()))),
144 Expr::Symbol("func".to_string()),
145 Expr::Symbol("list".to_string()),
146 ]);
147 let mapc_lambda = Expr::Lambda(mapc_params, Box::new(mapc_body));
148 self.define(Symbol::new("MAPC", SymbolKind::Macro).with_function(mapc_lambda));
149 }
150}