Skip to content

Commit

Permalink
support alist in bytecode
Browse files Browse the repository at this point in the history
  • Loading branch information
blahgeek committed Jan 3, 2024
1 parent 1cc9621 commit 51e7f49
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 8 deletions.
19 changes: 13 additions & 6 deletions src/bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ impl Op {
pub enum ObjectType {
Plist,
Hashtable,
// TODO: Alist,
Alist,
}

pub struct BytecodeOptions {
Expand Down Expand Up @@ -216,16 +216,22 @@ impl BytecodeCompiler {
}
}

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

for (key, value) in map {
self.compile_constant_op(LispObject::Keyword(key.clone()));
self.compile_value(value);
if alist {
self.compile_constant_op(LispObject::Symbol(key.clone()));
self.compile_value(value);
self.ops.push(Op::Cons);
} else {
self.compile_constant_op(LispObject::Keyword(key.clone()));
self.compile_value(value);
}
}

// four modes: 0. (empty) just nil 1. list op; 2. list call; 3. recursive cons
Expand Down Expand Up @@ -287,7 +293,8 @@ impl BytecodeCompiler {
},
&json::Value::Object(ref map) => {
match self.options.object_type {
ObjectType::Plist => self.compile_value_map_plist(&map),
ObjectType::Plist => self.compile_value_map_plist_or_alist(&map, false),
ObjectType::Alist => self.compile_value_map_plist_or_alist(&map, true),
ObjectType::Hashtable => self.compile_value_map_hashtable(&map),
};
},
Expand Down
14 changes: 13 additions & 1 deletion tests/benchmark_and_compare.template.el
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@
(setq p (cddr p)))
(sort res (lambda (a b) (string< (symbol-name (car a)) (symbol-name (car b)))))))

(defun -alistp (x)
(and (listp x)
(-all (lambda (e) (and (consp e) (symbolp (car e)))) x)))

(defun -sort-alist (x)
(sort x (lambda (a b) (string< (symbol-name (car a)) (symbol-name (car b))))))

(defun -hashtable-to-sorted-alist (h)
(let (res)
(maphash (lambda (k v) (push (cons k v) res)) h)
Expand Down Expand Up @@ -48,6 +55,11 @@
(equal (length a) (length b))
(-all (lambda (idx) (json-equal (aref a idx) (aref b idx)))
(number-sequence 0 (1- (length a))))))
((pred -alistp)
(and (-alistp b)
(equal (length a) (length b))
(-check-equal-sorted-alist (-sort-alist a)
(-sort-alist b))))
((pred plistp)
(and (plistp b)
(equal (length a) (length b))
Expand All @@ -66,7 +78,7 @@
(bytecode-str (with-temp-buffer
(insert-file-contents "{}")
(buffer-string)))
(object-type (if (equal "{}" "plist") 'plist 'hash-table))
(object-type (intern "{}"))
json-val bytecode-val)
(message "Object-type: %s" object-type)
(unless (json-equal (setq json-val
Expand Down
12 changes: 11 additions & 1 deletion tests/bytecode_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ fn run_one_test(json_str: &str, object_type: bytecode::ObjectType) -> Result<()>
bytecode_file.display(),
match object_type {
bytecode::ObjectType::Plist => "plist",
bytecode::ObjectType::Hashtable => "hashtable",
bytecode::ObjectType::Hashtable => "hash-table",
bytecode::ObjectType::Alist => "alist",
});
std::fs::write(&elisp_file, elisp_code.as_bytes())?;

Expand Down Expand Up @@ -68,25 +69,34 @@ fn test_huge_object() {
#[test]
fn test_completion_100k() {
run_one_test(include_str!("./data/completion.json"), bytecode::ObjectType::Plist).unwrap();
run_one_test(include_str!("./data/completion.json"), bytecode::ObjectType::Alist).unwrap();
run_one_test(include_str!("./data/completion.json"), bytecode::ObjectType::Hashtable).unwrap();
}

#[test]
fn test_completion_100k_2() {
run_one_test(include_str!("./data/completion2.json"), bytecode::ObjectType::Plist).unwrap();
run_one_test(include_str!("./data/completion2.json"), bytecode::ObjectType::Alist).unwrap();
run_one_test(include_str!("./data/completion2.json"), bytecode::ObjectType::Hashtable).unwrap();
}

#[test]
fn test_completion_4k() {
run_one_test(include_str!("./data/completion3.json"), bytecode::ObjectType::Plist).unwrap();
run_one_test(include_str!("./data/completion3.json"), bytecode::ObjectType::Alist).unwrap();
run_one_test(include_str!("./data/completion3.json"), bytecode::ObjectType::Hashtable).unwrap();
}

#[test]
fn test_diagnostics_12k() {
run_one_test(include_str!("./data/publishDiagnostics.json"), bytecode::ObjectType::Plist).unwrap();
run_one_test(include_str!("./data/publishDiagnostics.json"), bytecode::ObjectType::Alist).unwrap();
run_one_test(include_str!("./data/publishDiagnostics.json"), bytecode::ObjectType::Hashtable).unwrap();
}

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

0 comments on commit 51e7f49

Please sign in to comment.