add linked list
This commit is contained in:
parent
e48f06a8b5
commit
1c1f9a4566
4 changed files with 239 additions and 4 deletions
|
@ -13,12 +13,12 @@ construct _Iter {
|
|||
foreach { | with callable this ;
|
||||
!!-
|
||||
while { !!- this:next dup null eq not } {
|
||||
!!- callable call
|
||||
!!- callable callp
|
||||
}
|
||||
pop
|
||||
}
|
||||
collect { array | with this ;
|
||||
[ { any | } this:foreach ]
|
||||
[ { | } this:foreach ]
|
||||
}
|
||||
map { MapIter | with map-function this ;
|
||||
map-function this MapIter:new
|
||||
|
|
120
spl/linkedlist.spl
Normal file
120
spl/linkedlist.spl
Normal file
|
@ -0,0 +1,120 @@
|
|||
|
||||
construct LinkedList {
|
||||
next
|
||||
value
|
||||
;
|
||||
construct { this | }
|
||||
len { mega | with this ;
|
||||
def i this:value null eq not =i
|
||||
while { this:next null eq not } {
|
||||
this:next =this
|
||||
i ++ =i
|
||||
}
|
||||
i
|
||||
}
|
||||
push { this | with item this ;
|
||||
item:unwrap;
|
||||
this:value null eq if {
|
||||
item this:=value;
|
||||
this 2 stop
|
||||
}
|
||||
LinkedList:new
|
||||
dup :=value;<item>
|
||||
this:last-entry:=next;
|
||||
this
|
||||
}
|
||||
last-entry { list | with this ;
|
||||
while { this:next null eq not } {
|
||||
this:next =this
|
||||
}
|
||||
this
|
||||
}
|
||||
peek { value | with this ;
|
||||
this:last-entry:value
|
||||
}
|
||||
pop { item | with this ;
|
||||
def item this =item
|
||||
null
|
||||
while { item:next null eq not } {
|
||||
pop item
|
||||
item:next =item
|
||||
}
|
||||
"if theres no next item in this";
|
||||
dup null eq if {
|
||||
pop
|
||||
this:value (null this:=value;) 2 stop
|
||||
}
|
||||
:=next;<null>
|
||||
item:value
|
||||
}
|
||||
push-front { list | with item this ;
|
||||
item:unwrap;
|
||||
this:value null eq if {
|
||||
item this:=value;
|
||||
this 2 stop
|
||||
}
|
||||
LinkedList:new
|
||||
dup :=next;<this>
|
||||
dup :=value;<item>
|
||||
}
|
||||
insert { list | with item index this ;
|
||||
item:unwrap;
|
||||
index 0 eq if {
|
||||
item this:push-front 2 stop
|
||||
}
|
||||
def list this =list
|
||||
while { index 1 gt } {
|
||||
list:next =list
|
||||
index -- =index
|
||||
}
|
||||
item list:next:push-front list:=next;
|
||||
this
|
||||
}
|
||||
pop-front { item list | with this ;
|
||||
this:value this:next
|
||||
}
|
||||
remove { item list | with index this ;
|
||||
index 0 eq if {
|
||||
this:pop-front 2 stop
|
||||
}
|
||||
def list this =list
|
||||
while { index 1 gt } {
|
||||
list:next =list
|
||||
index -- =index
|
||||
}
|
||||
list:next:pop-front list:=next
|
||||
this
|
||||
}
|
||||
get { item | with index this ;
|
||||
while { index 0 gt } {
|
||||
this:next =this
|
||||
index -- =index
|
||||
}
|
||||
this:value
|
||||
}
|
||||
foreach { | with callable this ;
|
||||
while { this null eq not } {
|
||||
this:value dup null eq not if { callable:call; }
|
||||
this:next =this
|
||||
}
|
||||
}
|
||||
iter { LinkedListIter | with this ;
|
||||
this LinkedListIter:new
|
||||
}
|
||||
}
|
||||
|
||||
construct LinkedListIter {
|
||||
cur-list
|
||||
;
|
||||
construct { this | with list this ;
|
||||
list this:=cur-list
|
||||
this
|
||||
}
|
||||
next { item | with this ;
|
||||
this:cur-list dup null eq if { 2 stop }
|
||||
:value
|
||||
this:cur-list:next this:=cur-list;
|
||||
}
|
||||
}
|
||||
|
||||
include _Iter in LinkedListIter
|
|
@ -1,5 +1,5 @@
|
|||
use std::{
|
||||
collections::VecDeque,
|
||||
collections::{HashMap, VecDeque},
|
||||
env::{args, vars},
|
||||
fs,
|
||||
io::{stdin, stdout, Write},
|
||||
|
@ -930,9 +930,73 @@ pub fn mega_to_str_radix(stack: &mut Stack) -> OError {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
pub fn properties(stack: &mut Stack) -> OError {
|
||||
let o = stack.pop();
|
||||
let o = o.lock_ro();
|
||||
let additional: Vec<AMObject> = vec![
|
||||
Value::Array(vec![";".to_owned().spl(), o.native.clone().spl()]).spl(),
|
||||
Value::Array(vec![
|
||||
":".to_owned().spl(),
|
||||
o.kind.lock_ro().get_name().spl(),
|
||||
])
|
||||
.spl(),
|
||||
];
|
||||
stack.push(
|
||||
Value::Array(
|
||||
o.property_map
|
||||
.iter()
|
||||
.map(|(k, v)| Value::Array(vec![k.clone().spl(), v.clone()]).spl())
|
||||
.chain(additional.into_iter())
|
||||
.collect(),
|
||||
)
|
||||
.spl(),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn from_properties(stack: &mut Stack) -> OError {
|
||||
require_array_on_stack!(props, stack, "from-properties");
|
||||
let mut map = HashMap::with_capacity(props.len());
|
||||
for prop in props {
|
||||
require_array!(prop, prop, stack, "from-properties");
|
||||
if prop.len() != 2 {
|
||||
stack.err(ErrorKind::InvalidCall("from-properties".to_string()))?;
|
||||
}
|
||||
let Value::Str(ref s) = prop[0].lock_ro().native else {
|
||||
return Err(stack.error(ErrorKind::InvalidCall("from-properties".to_string())));
|
||||
};
|
||||
map.insert(s.to_owned(), prop[1].clone());
|
||||
}
|
||||
let Value::Str(kind) = map
|
||||
.get(":")
|
||||
.ok_or(stack.error(ErrorKind::InvalidCall("from-properties".to_string())))?
|
||||
.lock_ro()
|
||||
.native
|
||||
.clone()
|
||||
else {
|
||||
return Err(stack.error(ErrorKind::InvalidCall("from-properties".to_string())));
|
||||
};
|
||||
let kind = runtime(|rt| rt.get_type_by_name(&kind))
|
||||
.ok_or(stack.error(ErrorKind::TypeNotFound(kind.to_owned())))?;
|
||||
let native = map
|
||||
.get(";")
|
||||
.ok_or(stack.error(ErrorKind::InvalidCall("from-properties".to_owned())))?
|
||||
.lock_ro()
|
||||
.native
|
||||
.clone();
|
||||
map.remove(";");
|
||||
map.remove(":");
|
||||
stack.push(Arc::new(Mut::new(Object {
|
||||
kind,
|
||||
native,
|
||||
property_map: map,
|
||||
})));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn register(r: &mut Stack, o: Arc<Frame>) {
|
||||
type Fn = fn(&mut Stack) -> OError;
|
||||
let fns: [(&str, Fn, u32); 59] = [
|
||||
let fns: [(&str, Fn, u32); 61] = [
|
||||
("pop", pop, 0),
|
||||
("dup", dup, 2),
|
||||
("dup2", dup2, 3),
|
||||
|
@ -992,6 +1056,8 @@ pub fn register(r: &mut Stack, o: Arc<Frame>) {
|
|||
("str-readf", str_readf, 1),
|
||||
("str-to-mega-radix", str_to_mega_radix, 1),
|
||||
("mega-to-str-radix", mega_to_str_radix, 1),
|
||||
("properties", properties, 1),
|
||||
("from-properties", from_properties, 1),
|
||||
];
|
||||
for f in fns {
|
||||
r.define_func(
|
||||
|
|
49
test.spl
49
test.spl
|
@ -5,6 +5,7 @@
|
|||
"#server.spl" import
|
||||
"#time.spl" import
|
||||
"#httpserver/base.spl" import
|
||||
"#linkedlist.spl" import
|
||||
|
||||
|
||||
"SPL tester" =program-name
|
||||
|
@ -236,6 +237,54 @@ func main { int | with args ;
|
|||
|
||||
"hello! this is a test of URL encoding!" net:http:urlencode dup println;
|
||||
net:http:urldecode println;
|
||||
|
||||
"" println;
|
||||
"testing linked lists" println;
|
||||
|
||||
def list LinkedList:new =list
|
||||
"=> len of an empty list: " print;
|
||||
list:len println;
|
||||
|
||||
"=> len of a list with one element: " print;
|
||||
list:push;<"Hello!">
|
||||
list:len println;
|
||||
|
||||
"=> list should not have a next yet... " print;
|
||||
list:next null eq dup if { "ok" swap } not if { "BAD" } println
|
||||
|
||||
"=> element zero should be 'Hello!': " print list:get<0> println;
|
||||
|
||||
"=> iter of list should start with that too: " print list:iter dup:next println;
|
||||
"=> then should be null: " print :next dup null eq if { pop "ok" } println;
|
||||
|
||||
"=> list should contain 'Hello!': " print list:iter:join<", "> println;
|
||||
|
||||
"=> with new element after that: " print
|
||||
list:push;<"One!!">
|
||||
list:iter:join<", "> println;
|
||||
|
||||
"=> pushing numbers 2..10: " print
|
||||
2 10 Range:new:iter:foreach;<{ | list:push; }>
|
||||
list:iter:join<", "> println;
|
||||
|
||||
"=> popping 9: " print
|
||||
list:pop;
|
||||
list:iter:join<", "> println;
|
||||
"=> removing 5: " print
|
||||
list:remove<5> =list pop
|
||||
list:iter:join<", "> println;
|
||||
"=> popping front: " print
|
||||
list:pop-front =list pop
|
||||
list:iter:join<", "> println;
|
||||
|
||||
"=> inserting 0 back: " print
|
||||
0 list:insert<0> =list
|
||||
list:iter:join<", "> println;
|
||||
|
||||
"=> inserting 5 back: " print
|
||||
5 list:insert<5> =list
|
||||
list:iter:join<", "> println;
|
||||
|
||||
|
||||
5 :foreach<{ | "" println }>
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue