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 ;
|
foreach { | with callable this ;
|
||||||
!!-
|
!!-
|
||||||
while { !!- this:next dup null eq not } {
|
while { !!- this:next dup null eq not } {
|
||||||
!!- callable call
|
!!- callable callp
|
||||||
}
|
}
|
||||||
pop
|
pop
|
||||||
}
|
}
|
||||||
collect { array | with this ;
|
collect { array | with this ;
|
||||||
[ { any | } this:foreach ]
|
[ { | } this:foreach ]
|
||||||
}
|
}
|
||||||
map { MapIter | with map-function this ;
|
map { MapIter | with map-function this ;
|
||||||
map-function this MapIter:new
|
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::{
|
use std::{
|
||||||
collections::VecDeque,
|
collections::{HashMap, VecDeque},
|
||||||
env::{args, vars},
|
env::{args, vars},
|
||||||
fs,
|
fs,
|
||||||
io::{stdin, stdout, Write},
|
io::{stdin, stdout, Write},
|
||||||
|
@ -930,9 +930,73 @@ pub fn mega_to_str_radix(stack: &mut Stack) -> OError {
|
||||||
return Ok(());
|
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>) {
|
pub fn register(r: &mut Stack, o: Arc<Frame>) {
|
||||||
type Fn = fn(&mut Stack) -> OError;
|
type Fn = fn(&mut Stack) -> OError;
|
||||||
let fns: [(&str, Fn, u32); 59] = [
|
let fns: [(&str, Fn, u32); 61] = [
|
||||||
("pop", pop, 0),
|
("pop", pop, 0),
|
||||||
("dup", dup, 2),
|
("dup", dup, 2),
|
||||||
("dup2", dup2, 3),
|
("dup2", dup2, 3),
|
||||||
|
@ -992,6 +1056,8 @@ pub fn register(r: &mut Stack, o: Arc<Frame>) {
|
||||||
("str-readf", str_readf, 1),
|
("str-readf", str_readf, 1),
|
||||||
("str-to-mega-radix", str_to_mega_radix, 1),
|
("str-to-mega-radix", str_to_mega_radix, 1),
|
||||||
("mega-to-str-radix", mega_to_str_radix, 1),
|
("mega-to-str-radix", mega_to_str_radix, 1),
|
||||||
|
("properties", properties, 1),
|
||||||
|
("from-properties", from_properties, 1),
|
||||||
];
|
];
|
||||||
for f in fns {
|
for f in fns {
|
||||||
r.define_func(
|
r.define_func(
|
||||||
|
|
49
test.spl
49
test.spl
|
@ -5,6 +5,7 @@
|
||||||
"#server.spl" import
|
"#server.spl" import
|
||||||
"#time.spl" import
|
"#time.spl" import
|
||||||
"#httpserver/base.spl" import
|
"#httpserver/base.spl" import
|
||||||
|
"#linkedlist.spl" import
|
||||||
|
|
||||||
|
|
||||||
"SPL tester" =program-name
|
"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;
|
"hello! this is a test of URL encoding!" net:http:urlencode dup println;
|
||||||
net:http:urldecode 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 }>
|
5 :foreach<{ | "" println }>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue