Skip to content

Commit 433d4e0

Browse files
committed
WIP
1 parent d7714a1 commit 433d4e0

3 files changed

Lines changed: 130 additions & 1 deletion

File tree

bridge_adapters/src/lisp_adapters/collections.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::lisp_adapters::{SlFromRef, SlFromRefMut};
1+
use crate::lisp_adapters::{SlAsMut, SlAsRef, SlFromRef, SlFromRefMut};
22
use bridge_types::ErrorStrings;
33
use compile_state::state::SloshVm;
44
use slvm::vm_hashmap::VMHashMap;
@@ -31,3 +31,31 @@ impl<'a> SlFromRefMut<'a, Value> for &'a mut VMHashMap {
3131
}
3232
}
3333
}
34+
35+
impl<'a> SlAsRef<'a, VMHashMap> for &'a Value {
36+
fn sl_as_ref(&self, vm: &'a SloshVm) -> VMResult<&'a VMHashMap> {
37+
match self {
38+
Value::Map(h) => Ok(vm.get_map(*h)),
39+
_ => Err(VMError::new_conversion(
40+
ErrorStrings::fix_me_mismatched_type(
41+
<&'static str>::from(ValueType::Map),
42+
self.display_type(vm),
43+
),
44+
)),
45+
}
46+
}
47+
}
48+
49+
impl<'a> SlAsMut<'a, VMHashMap> for &'a Value {
50+
fn sl_as_mut(&mut self, vm: &'a mut SloshVm) -> VMResult<&'a mut VMHashMap> {
51+
match self {
52+
Value::Map(h) => vm.get_map_mut(*h),
53+
_ => Err(VMError::new_conversion(
54+
ErrorStrings::fix_me_mismatched_type(
55+
<&'static str>::from(ValueType::Map),
56+
self.display_type(vm),
57+
),
58+
)),
59+
}
60+
}
61+
}

bridge_macros/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,6 +1619,7 @@ pub fn sl_sh_fn(
16191619
#generated_code
16201620

16211621
#[allow(dead_code)]
1622+
#[inline(always)]
16221623
#original_fn_code
16231624
}
16241625
}

slosh_lib/src/debug.rs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use compile_state::state::{SloshVm, SloshVmTrait};
1010
use sl_compiler::Reader;
1111
use sl_liner::{Context, Prompt};
1212
use slvm::{CallFrame, Chunk, VMError, VMResult, Value};
13+
use slvm::vm_hashmap::VMHashMap;
1314

1415
fn dump_regs(vm: &SloshVm, frame: &CallFrame) {
1516
let start = frame.stack_top;
@@ -355,3 +356,102 @@ macro_rules! file_println {
355356
}
356357
};
357358
}
359+
360+
#[doc = " Usage: (hash-haskey hashmap key)"]
361+
#[doc = ""]
362+
#[doc = " Checks if a key is in a hashmap."]
363+
#[doc = ""]
364+
#[doc = " Section: hashmap"]
365+
#[doc = ""]
366+
#[doc = " Example:"]
367+
#[doc = " (def tst-hash {:key1 \"val one\" \'key2 \"val two\" \"key3\" \"val three\" \\S \"val S\"})"]
368+
#[doc = " (test::assert-equal 4 (len (hash-keys tst-hash)))"]
369+
#[doc = " (test::assert-true (hash-haskey tst-hash :key1))"]
370+
#[doc = " (test::assert-true (hash-haskey tst-hash \'key2))"]
371+
#[doc = " (test::assert-true (hash-haskey tst-hash \"key3\"))"]
372+
#[doc = " (test::assert-true (hash-haskey tst-hash \\S))"]
373+
#[doc = " (test::assert-false (hash-haskey tst-hash \'key1))"]
374+
#[doc = " (test::assert-false (hash-haskey tst-hash :key2))"]
375+
#[doc = " (test::assert-false (hash-haskey tst-hash \"keynone\"))"]
376+
#[doc = " (hash-remove! tst-hash :key1)"]
377+
#[doc = " (test::assert-false (hash-haskey tst-hash :key1))"]
378+
#[doc = " (set! tst-hash :key1 \"val one b\")"]
379+
#[doc = " (test::assert-true (hash-haskey tst-hash :key1))"]
380+
381+
fn parse_hash_hashkey(environment: &mut compile_state::state::SloshVm, args: &[slvm::Value] ) -> slvm::VMResult<slvm::Value> {
382+
let fn_name = "hash-haskey?"; const PARAMS_LEN: usize = 2usize;
383+
let arg_types: [bridge_types::Param; PARAMS_LEN] = [bridge_types::Param { handle: bridge_types::TypeHandle::Direct, passing_style: bridge_types::PassingStyle::Reference }, bridge_types::Param { handle: bridge_types::TypeHandle::Direct, passing_style: bridge_types::PassingStyle::Value }];
384+
static_assertions::assert_impl_all!(Value : bridge_adapters :: lisp_adapters :: SlInto < slvm :: Value > );
385+
let param = arg_types[1usize];
386+
match param.handle {
387+
bridge_types::TypeHandle::Direct => match args.get(1usize) {
388+
None => { return Err(slvm::VMError::new_vm(format!("{} not given enough arguments, expected at least {} arguments, got {}.", fn_name, 2usize, args.len()))); }
389+
Some(arg_1) => {
390+
let arg_1 = *arg_1;
391+
{
392+
use bridge_adapters::lisp_adapters::SlIntoRef;
393+
let arg_1: Value = arg_1.sl_into_ref(environment)?;
394+
let param = arg_types[0usize];
395+
match param.handle {
396+
bridge_types::TypeHandle::Direct => match args.get(0usize) {
397+
None => { return Err(slvm::VMError::new_vm(format!("{} not given enough arguments, expected at least {} arguments, got {}.", fn_name, 2usize, args.len()))); }
398+
Some(arg_0) => {
399+
{
400+
use bridge_adapters::lisp_adapters::SlAsRef;
401+
let arg_0: &slvm::vm_hashmap::VMHashMap = arg_0.sl_as_ref(environment)?;
402+
match args.get(PARAMS_LEN) {
403+
Some(_) if PARAMS_LEN == 0 || arg_types[PARAMS_LEN - 1].handle != bridge_types::TypeHandle::VarArgs => { return Err(slvm::VMError::new_vm(format!("{} given too many arguments, expected at least {} arguments, got {}.", fn_name, 2usize, args.len()))); }
404+
_ => {
405+
use bridge_adapters::lisp_adapters::SlInto;
406+
if arg_0.contains_key(environment, arg_1) {
407+
Ok(Value::True)
408+
} else {
409+
Ok(Value::False)
410+
}
411+
}
412+
}
413+
}
414+
}
415+
},
416+
_ => { return Err(slvm::VMError::new_vm(format!("{} failed to parse its arguments, internal error.", fn_name, ))); }
417+
}
418+
}
419+
}
420+
},
421+
_ => { return Err(slvm::VMError::new_vm(format!("{} failed to parse its arguments, internal error.", fn_name, ))); }
422+
}
423+
}
424+
fn intern_hash_hashkey(env: &mut compile_state::state::SloshVm) {
425+
let fn_name = "hash-haskey?";
426+
bridge_adapters::add_builtin(env, fn_name, parse_hash_hashkey, "Usage: (hash-haskey hashmap key)\n\nChecks if a key is in a hashmap.\n\nSection: hashmap\n\nExample:\n(def tst-hash {:key1 \"val one\" 'key2 \"val two\" \"key3\" \"val three\" \\S \"val S\"})\n(test::assert-equal 4 (len (hash-keys tst-hash)))\n(test::assert-true (hash-haskey tst-hash :key1))\n(test::assert-true (hash-haskey tst-hash 'key2))\n(test::assert-true (hash-haskey tst-hash \"key3\"))\n(test::assert-true (hash-haskey tst-hash \\S))\n(test::assert-false (hash-haskey tst-hash 'key1))\n(test::assert-false (hash-haskey tst-hash :key2))\n(test::assert-false (hash-haskey tst-hash \"keynone\"))\n(hash-remove! tst-hash :key1)\n(test::assert-false (hash-haskey tst-hash :key1))\n(set! tst-hash :key1 \"val one b\")\n(test::assert-true (hash-haskey tst-hash :key1))\n");
427+
}
428+
#[allow(dead_code)]
429+
#[inline(always)]
430+
#[doc = " Usage: (hash-haskey hashmap key)"]
431+
#[doc = ""]
432+
#[doc = " Checks if a key is in a hashmap."]
433+
#[doc = ""]
434+
#[doc = " Section: hashmap"]
435+
#[doc = ""]
436+
#[doc = " Example:"]
437+
#[doc = " (def tst-hash {:key1 \"val one\" \'key2 \"val two\" \"key3\" \"val three\" \\S \"val S\"})"]
438+
#[doc = " (test::assert-equal 4 (len (hash-keys tst-hash)))"]
439+
#[doc = " (test::assert-true (hash-haskey tst-hash :key1))"]
440+
#[doc = " (test::assert-true (hash-haskey tst-hash \'key2))"]
441+
#[doc = " (test::assert-true (hash-haskey tst-hash \"key3\"))"]
442+
#[doc = " (test::assert-true (hash-haskey tst-hash \\S))"]
443+
#[doc = " (test::assert-false (hash-haskey tst-hash \'key1))"]
444+
#[doc = " (test::assert-false (hash-haskey tst-hash :key2))"]
445+
#[doc = " (test::assert-false (hash-haskey tst-hash \"keynone\"))"]
446+
#[doc = " (hash-remove! tst-hash :key1)"]
447+
#[doc = " (test::assert-false (hash-haskey tst-hash :key1))"]
448+
#[doc = " (set! tst-hash :key1 \"val one b\")"]
449+
#[doc = " (test::assert-true (hash-haskey tst-hash :key1))"]
450+
451+
pub fn hash_hashkey(environment: &mut SloshVm, map: &slvm::vm_hashmap::VMHashMap, key: Value) -> VMResult<Value> {
452+
if map.contains_key(environment, key) {
453+
Ok(Value::True)
454+
} else {
455+
Ok(Value::False)
456+
}
457+
}

0 commit comments

Comments
 (0)