Skip to content

Commit 51e7f49

Browse files
committed
support alist in bytecode
1 parent 1cc9621 commit 51e7f49

File tree

3 files changed

+37
-8
lines changed

3 files changed

+37
-8
lines changed

src/bytecode.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ impl Op {
143143
pub enum ObjectType {
144144
Plist,
145145
Hashtable,
146-
// TODO: Alist,
146+
Alist,
147147
}
148148

149149
pub struct BytecodeOptions {
@@ -216,16 +216,22 @@ impl BytecodeCompiler {
216216
}
217217
}
218218

219-
fn compile_value_map_plist(&mut self, map: &json::Map<String, json::Value>) {
220-
let list_len = map.len() * 2;
219+
fn compile_value_map_plist_or_alist(&mut self, map: &json::Map<String, json::Value>, alist: bool) {
220+
let list_len = if alist { map.len() } else { map.len() * 2 };
221221
// see below
222222
if list_len < (1 << 16) && list_len >= (1 << 8) {
223223
self.compile_constant_op(LispObject::Symbol("list".into()));
224224
}
225225

226226
for (key, value) in map {
227-
self.compile_constant_op(LispObject::Keyword(key.clone()));
228-
self.compile_value(value);
227+
if alist {
228+
self.compile_constant_op(LispObject::Symbol(key.clone()));
229+
self.compile_value(value);
230+
self.ops.push(Op::Cons);
231+
} else {
232+
self.compile_constant_op(LispObject::Keyword(key.clone()));
233+
self.compile_value(value);
234+
}
229235
}
230236

231237
// four modes: 0. (empty) just nil 1. list op; 2. list call; 3. recursive cons
@@ -287,7 +293,8 @@ impl BytecodeCompiler {
287293
},
288294
&json::Value::Object(ref map) => {
289295
match self.options.object_type {
290-
ObjectType::Plist => self.compile_value_map_plist(&map),
296+
ObjectType::Plist => self.compile_value_map_plist_or_alist(&map, false),
297+
ObjectType::Alist => self.compile_value_map_plist_or_alist(&map, true),
291298
ObjectType::Hashtable => self.compile_value_map_hashtable(&map),
292299
};
293300
},

tests/benchmark_and_compare.template.el

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919
(setq p (cddr p)))
2020
(sort res (lambda (a b) (string< (symbol-name (car a)) (symbol-name (car b)))))))
2121

22+
(defun -alistp (x)
23+
(and (listp x)
24+
(-all (lambda (e) (and (consp e) (symbolp (car e)))) x)))
25+
26+
(defun -sort-alist (x)
27+
(sort x (lambda (a b) (string< (symbol-name (car a)) (symbol-name (car b))))))
28+
2229
(defun -hashtable-to-sorted-alist (h)
2330
(let (res)
2431
(maphash (lambda (k v) (push (cons k v) res)) h)
@@ -48,6 +55,11 @@
4855
(equal (length a) (length b))
4956
(-all (lambda (idx) (json-equal (aref a idx) (aref b idx)))
5057
(number-sequence 0 (1- (length a))))))
58+
((pred -alistp)
59+
(and (-alistp b)
60+
(equal (length a) (length b))
61+
(-check-equal-sorted-alist (-sort-alist a)
62+
(-sort-alist b))))
5163
((pred plistp)
5264
(and (plistp b)
5365
(equal (length a) (length b))
@@ -66,7 +78,7 @@
6678
(bytecode-str (with-temp-buffer
6779
(insert-file-contents "{}")
6880
(buffer-string)))
69-
(object-type (if (equal "{}" "plist") 'plist 'hash-table))
81+
(object-type (intern "{}"))
7082
json-val bytecode-val)
7183
(message "Object-type: %s" object-type)
7284
(unless (json-equal (setq json-val

tests/bytecode_test.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ fn run_one_test(json_str: &str, object_type: bytecode::ObjectType) -> Result<()>
3030
bytecode_file.display(),
3131
match object_type {
3232
bytecode::ObjectType::Plist => "plist",
33-
bytecode::ObjectType::Hashtable => "hashtable",
33+
bytecode::ObjectType::Hashtable => "hash-table",
34+
bytecode::ObjectType::Alist => "alist",
3435
});
3536
std::fs::write(&elisp_file, elisp_code.as_bytes())?;
3637

@@ -68,25 +69,34 @@ fn test_huge_object() {
6869
#[test]
6970
fn test_completion_100k() {
7071
run_one_test(include_str!("./data/completion.json"), bytecode::ObjectType::Plist).unwrap();
72+
run_one_test(include_str!("./data/completion.json"), bytecode::ObjectType::Alist).unwrap();
7173
run_one_test(include_str!("./data/completion.json"), bytecode::ObjectType::Hashtable).unwrap();
7274
}
7375

7476
#[test]
7577
fn test_completion_100k_2() {
7678
run_one_test(include_str!("./data/completion2.json"), bytecode::ObjectType::Plist).unwrap();
79+
run_one_test(include_str!("./data/completion2.json"), bytecode::ObjectType::Alist).unwrap();
80+
run_one_test(include_str!("./data/completion2.json"), bytecode::ObjectType::Hashtable).unwrap();
7781
}
7882

7983
#[test]
8084
fn test_completion_4k() {
8185
run_one_test(include_str!("./data/completion3.json"), bytecode::ObjectType::Plist).unwrap();
86+
run_one_test(include_str!("./data/completion3.json"), bytecode::ObjectType::Alist).unwrap();
87+
run_one_test(include_str!("./data/completion3.json"), bytecode::ObjectType::Hashtable).unwrap();
8288
}
8389

8490
#[test]
8591
fn test_diagnostics_12k() {
8692
run_one_test(include_str!("./data/publishDiagnostics.json"), bytecode::ObjectType::Plist).unwrap();
93+
run_one_test(include_str!("./data/publishDiagnostics.json"), bytecode::ObjectType::Alist).unwrap();
94+
run_one_test(include_str!("./data/publishDiagnostics.json"), bytecode::ObjectType::Hashtable).unwrap();
8795
}
8896

8997
#[test]
9098
fn test_diagnostics_12k_2() {
9199
run_one_test(include_str!("./data/publishDiagnostics2.json"), bytecode::ObjectType::Plist).unwrap();
100+
run_one_test(include_str!("./data/publishDiagnostics2.json"), bytecode::ObjectType::Alist).unwrap();
101+
run_one_test(include_str!("./data/publishDiagnostics2.json"), bytecode::ObjectType::Hashtable).unwrap();
92102
}

0 commit comments

Comments
 (0)