implement vectors
This commit is contained in:
+5
-31
@@ -1,36 +1,10 @@
|
|||||||
|
(define-module automata
|
||||||
|
:exports (make-dfa)
|
||||||
(import "sets.slime")
|
(import "sets.slime")
|
||||||
|
|
||||||
|
|
||||||
(define (make-dfa Q S delta q0 F)
|
(define (make-dfa Q S delta q0 F)
|
||||||
(let ((q q0))
|
(let ((q q0))
|
||||||
(lambda (s)
|
(lambda (s)
|
||||||
(mutate q (delta q s))
|
(set! q (delta q s))
|
||||||
`(,(if (set-contains? F q) :accept :fail) ,q))))
|
(list (if (set::contains? F q) :accept :fail) q))))
|
||||||
|
)
|
||||||
|
|
||||||
(define (delta q s)
|
|
||||||
(cond (s (case q
|
|
||||||
(("q0") (case s (("M") "q1")))
|
|
||||||
(("q1") (case s (("A") "q0")
|
|
||||||
(("G") "q2")))
|
|
||||||
(("q2") (case s (("E") "q0")))))
|
|
||||||
(else q)))
|
|
||||||
|
|
||||||
|
|
||||||
;; (make-delta
|
|
||||||
;; ("q0" :: "M" -> "q1")
|
|
||||||
;; ("q1" :: "A" -> "q0"
|
|
||||||
;; "G" -> "q1")
|
|
||||||
;; ("q2" :: "E" -> "q0"))
|
|
||||||
|
|
||||||
(define aut (make-dfa (make-set "q0" "q1" "q2")
|
|
||||||
(make-set "M" "A" "G" "E")
|
|
||||||
delta
|
|
||||||
"q0"
|
|
||||||
(make-set "q0")))
|
|
||||||
|
|
||||||
(printf (aut "M"))
|
|
||||||
(printf (aut "A"))
|
|
||||||
(printf (aut "M"))
|
|
||||||
(printf (aut "G"))
|
|
||||||
(printf (aut "E"))
|
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
|
||||||
(define-package interpolation
|
(define-module interpolation
|
||||||
|
:exports (lerp lerper stepped-lerper
|
||||||
|
point-lerp point-lerper
|
||||||
|
bezier2 bezierer2)
|
||||||
|
|
||||||
(define-typed (lerp a :number b :number t :number)
|
(define-typed (lerp a :number b :number t :number)
|
||||||
(+ (* t (- b a)) a))
|
(+ (* t (- b a)) a))
|
||||||
@@ -43,5 +46,5 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
(define sl1 (interpolation-> stepped-lerper 0 1 5))
|
(define sl1 (interpolation::stepped-lerper 0 1 5))
|
||||||
(define sl2 (interpolation-> stepped-lerper 10 -10 20))
|
(define sl2 (interpolation::stepped-lerper 10 -10 20))
|
||||||
|
|||||||
+3
-2
@@ -1,6 +1,7 @@
|
|||||||
(import "oo.slime")
|
(define-module math
|
||||||
|
:exports (pi abs sqrt make-vector3)
|
||||||
|
|
||||||
(define-package math
|
(import "oo.slime")
|
||||||
|
|
||||||
(define pi
|
(define pi
|
||||||
"Tha famous circle constant."
|
"Tha famous circle constant."
|
||||||
|
|||||||
+29
-12
@@ -1,3 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
(define-syntax (pe expr)
|
(define-syntax (pe expr)
|
||||||
`(printf ',expr "evaluates to" ,expr))
|
`(printf ',expr "evaluates to" ,expr))
|
||||||
|
|
||||||
@@ -141,18 +143,33 @@ ithe sequence as arguemens."
|
|||||||
(assert-types= @lambda-list)
|
(assert-types= @lambda-list)
|
||||||
@body)))
|
@body)))
|
||||||
|
|
||||||
(define-syntax (define-package name :rest body)
|
|
||||||
`(define ,(string->symbol (concat-strings (symbol->string name) "->"))
|
(define-syntax (define-module module-name :keys exports :rest body)
|
||||||
((lambda ()
|
(let ((module-prefix (concat-strings (symbol->string module-name) "::")))
|
||||||
@body
|
(eval `(begin @body))
|
||||||
(set-type
|
(pair 'begin
|
||||||
(special-lambda (:rest args)
|
(map (lambda (orig-export-name)
|
||||||
(let ((op (first args))
|
(let ((export-name (string->symbol
|
||||||
(args (rest args)))
|
(concat-strings module-prefix
|
||||||
(if (callable? (eval op))
|
(symbol->string orig-export-name)))))
|
||||||
(apply op args)
|
`(define ,export-name
|
||||||
(eval op))))
|
,(try (eval orig-export-name)
|
||||||
:package)))))
|
(error "The module does not contain" orig-export-name)))))
|
||||||
|
exports))))
|
||||||
|
|
||||||
|
|
||||||
|
;; (define-syntax (define-package name :rest body)
|
||||||
|
;; `(define ,(string->symbol (concat-strings (symbol->string name) "->"))
|
||||||
|
;; ((lambda ()
|
||||||
|
;; @body
|
||||||
|
;; (set-type
|
||||||
|
;; (special-lambda (:rest args)
|
||||||
|
;; (let ((op (first args))
|
||||||
|
;; (args (rest args)))
|
||||||
|
;; (if (callable? (eval op))
|
||||||
|
;; (apply op args)
|
||||||
|
;; (eval op))))
|
||||||
|
;; :package)))))
|
||||||
|
|
||||||
(define (null? x)
|
(define (null? x)
|
||||||
"Checks if the argument is =nil=."
|
"Checks if the argument is =nil=."
|
||||||
|
|||||||
+12
-7
@@ -1,15 +1,18 @@
|
|||||||
|
(define-module set
|
||||||
|
:exports (make find contains? insert!)
|
||||||
|
|
||||||
(import "cxr.slime")
|
(import "cxr.slime")
|
||||||
|
|
||||||
(define key-not-found-index -1)
|
(define key-not-found-index -1)
|
||||||
|
|
||||||
(define (make-set :rest vals)
|
(define (make :rest vals)
|
||||||
(set-type
|
(set-type
|
||||||
(if vals
|
(if vals
|
||||||
(list vals)
|
(list vals)
|
||||||
'(()))
|
'(()))
|
||||||
:set))
|
:set))
|
||||||
|
|
||||||
(define (set-find set val)
|
(define (find set val)
|
||||||
(let ((values (car set)))
|
(let ((values (car set)))
|
||||||
(define (inner values current-index)
|
(define (inner values current-index)
|
||||||
(cond ((null? values) key-not-found-index)
|
(cond ((null? values) key-not-found-index)
|
||||||
@@ -17,12 +20,14 @@
|
|||||||
(else (inner (cdr values) (+ 1 current-index)))))
|
(else (inner (cdr values) (+ 1 current-index)))))
|
||||||
(inner values 0)))
|
(inner values 0)))
|
||||||
|
|
||||||
(define (set-contains? set val)
|
(define (contains? set val)
|
||||||
(unless (= (set-find set val) key-not-found-index)
|
(unless (= (find set val) key-not-found-index)
|
||||||
t))
|
t))
|
||||||
|
|
||||||
(define (set-insert! set value)
|
(define (insert! set value)
|
||||||
(unless (set-contains? set value)
|
(unless (contains? set value)
|
||||||
(mutate set (pair (pair value (first set)) ()))
|
(set! set (pair (pair value (first set)) ()))
|
||||||
(set-type set :set))
|
(set-type set :set))
|
||||||
set)
|
set)
|
||||||
|
|
||||||
|
)
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
(import "sets.slime")
|
||||||
|
(import "automata.slime")
|
||||||
|
|
||||||
|
;; (make-delta
|
||||||
|
;; ("q0" :: "M" -> "q1")
|
||||||
|
;; ("q1" :: "A" -> "q0"
|
||||||
|
;; "G" -> "q1")
|
||||||
|
;; ("q2" :: "E" -> "q0"))
|
||||||
|
|
||||||
|
(define (delta q s)
|
||||||
|
(cond (s (case q
|
||||||
|
(("q0") (case s (("M") "q1")))
|
||||||
|
(("q1") (case s (("A") "q0")
|
||||||
|
(("G") "q2")))
|
||||||
|
(("q2") (case s (("E") "q0")))))
|
||||||
|
(else q)))
|
||||||
|
|
||||||
|
(define aut (automata::make-dfa (set::make "q0" "q1" "q2")
|
||||||
|
(set::make "M" "A" "G" "E")
|
||||||
|
delta
|
||||||
|
"q0"
|
||||||
|
(set::make "q0")))
|
||||||
|
|
||||||
|
(let ((state (aut ())))
|
||||||
|
(assert (= (first state) :accept))
|
||||||
|
(assert (= (first (rest state)) "q0")))
|
||||||
|
|
||||||
|
(let ((state (aut "M")))
|
||||||
|
(assert (= (first state) :fail))
|
||||||
|
(assert (= (first (rest state)) "q1")))
|
||||||
|
|
||||||
|
(let ((state (aut "A")))
|
||||||
|
(assert (= (first state) :accept))
|
||||||
|
(assert (= (first (rest state)) "q0")))
|
||||||
|
|
||||||
|
(let ((state (aut "M")))
|
||||||
|
(assert (= (first state) :fail))
|
||||||
|
(assert (= (first (rest state)) "q1")))
|
||||||
|
|
||||||
|
(let ((state (aut "G")))
|
||||||
|
(assert (= (first state) :fail))
|
||||||
|
(assert (= (first (rest state)) "q2")))
|
||||||
|
|
||||||
|
(let ((state (aut "E")))
|
||||||
|
(assert (= (first state) :accept))
|
||||||
|
(assert (= (first (rest state)) "q0")))
|
||||||
+65
-1050
File diff suppressed because it is too large
Load Diff
+31
-1
@@ -22,6 +22,7 @@ proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool {
|
|||||||
case Lisp_Object_Type::Number: return n1->value.number == n2->value.number;
|
case Lisp_Object_Type::Number: return n1->value.number == n2->value.number;
|
||||||
case Lisp_Object_Type::String: return string_equal(n1->value.string, n2->value.string);
|
case Lisp_Object_Type::String: return string_equal(n1->value.string, n2->value.string);
|
||||||
case Lisp_Object_Type::Pair:
|
case Lisp_Object_Type::Pair:
|
||||||
|
case Lisp_Object_Type::Vector:
|
||||||
create_not_yet_implemented_error();
|
create_not_yet_implemented_error();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -456,7 +457,7 @@ proc load_built_ins_into_environment() -> void {
|
|||||||
try assert_type(target_symbol, Lisp_Object_Type::Symbol);
|
try assert_type(target_symbol, Lisp_Object_Type::Symbol);
|
||||||
|
|
||||||
Environment* target_env = find_binding_environment(target_symbol->value.symbol.identifier, get_current_environment());
|
Environment* target_env = find_binding_environment(target_symbol->value.symbol.identifier, get_current_environment());
|
||||||
assert(target_env);
|
try assert(target_env);
|
||||||
|
|
||||||
push_environment(target_env);
|
push_environment(target_env);
|
||||||
defer {
|
defer {
|
||||||
@@ -465,6 +466,28 @@ proc load_built_ins_into_environment() -> void {
|
|||||||
|
|
||||||
define_symbol(target_symbol, source);
|
define_symbol(target_symbol, source);
|
||||||
|
|
||||||
|
return source;
|
||||||
|
});
|
||||||
|
defun("set-car!", "TODO", __LINE__, cLambda {
|
||||||
|
try evaluated_arguments = eval_arguments(arguments, &arguments_length);
|
||||||
|
try assert_arguments_length(2, arguments_length);
|
||||||
|
Lisp_Object* target = evaluated_arguments->value.pair.first;
|
||||||
|
Lisp_Object* source = evaluated_arguments->value.pair.rest->value.pair.first;
|
||||||
|
|
||||||
|
assert_type(target, Lisp_Object_Type::Pair);
|
||||||
|
|
||||||
|
*target->value.pair.first = *source;
|
||||||
|
return source;
|
||||||
|
});
|
||||||
|
defun("set-cdr!", "TODO", __LINE__, cLambda {
|
||||||
|
try evaluated_arguments = eval_arguments(arguments, &arguments_length);
|
||||||
|
try assert_arguments_length(2, arguments_length);
|
||||||
|
Lisp_Object* target = evaluated_arguments->value.pair.first;
|
||||||
|
Lisp_Object* source = evaluated_arguments->value.pair.rest->value.pair.first;
|
||||||
|
|
||||||
|
assert_type(target, Lisp_Object_Type::Pair);
|
||||||
|
|
||||||
|
*target->value.pair.rest = *source;
|
||||||
return source;
|
return source;
|
||||||
});
|
});
|
||||||
defun("if", "TODO", __LINE__, cLambda {
|
defun("if", "TODO", __LINE__, cLambda {
|
||||||
@@ -750,6 +773,12 @@ proc load_built_ins_into_environment() -> void {
|
|||||||
try evaluated_arguments = eval_arguments(arguments, &arguments_length);
|
try evaluated_arguments = eval_arguments(arguments, &arguments_length);
|
||||||
return evaluated_arguments;
|
return evaluated_arguments;
|
||||||
});
|
});
|
||||||
|
defun("vector", "TODO", __LINE__, cLambda {
|
||||||
|
try evaluated_arguments = eval_arguments(arguments, &arguments_length);
|
||||||
|
Lisp_Object* ret;
|
||||||
|
try ret = Memory::create_lisp_object_vector(arguments_length, evaluated_arguments);
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
defun("pair", "TODO", __LINE__, cLambda {
|
defun("pair", "TODO", __LINE__, cLambda {
|
||||||
try evaluated_arguments = eval_arguments(arguments, &arguments_length);
|
try evaluated_arguments = eval_arguments(arguments, &arguments_length);
|
||||||
try assert_arguments_length(2, arguments_length);
|
try assert_arguments_length(2, arguments_length);
|
||||||
@@ -829,6 +858,7 @@ proc load_built_ins_into_environment() -> void {
|
|||||||
case Lisp_Object_Type::T: return Memory::get_or_create_lisp_object_keyword("t");
|
case Lisp_Object_Type::T: return Memory::get_or_create_lisp_object_keyword("t");
|
||||||
case Lisp_Object_Type::Number: return Memory::get_or_create_lisp_object_keyword("number");
|
case Lisp_Object_Type::Number: return Memory::get_or_create_lisp_object_keyword("number");
|
||||||
case Lisp_Object_Type::Pair: return Memory::get_or_create_lisp_object_keyword("pair");
|
case Lisp_Object_Type::Pair: return Memory::get_or_create_lisp_object_keyword("pair");
|
||||||
|
case Lisp_Object_Type::Vector: return Memory::get_or_create_lisp_object_keyword("vector");
|
||||||
case Lisp_Object_Type::String: return Memory::get_or_create_lisp_object_keyword("string");
|
case Lisp_Object_Type::String: return Memory::get_or_create_lisp_object_keyword("string");
|
||||||
case Lisp_Object_Type::Symbol: return Memory::get_or_create_lisp_object_keyword("symbol");
|
case Lisp_Object_Type::Symbol: return Memory::get_or_create_lisp_object_keyword("symbol");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -294,6 +294,14 @@ proc print(Lisp_Object* node, bool print_repr = false, FILE* file = stdout) -> v
|
|||||||
else
|
else
|
||||||
fputs(Memory::get_c_str(node->value.string), file);
|
fputs(Memory::get_c_str(node->value.string), file);
|
||||||
} break;
|
} break;
|
||||||
|
case (Lisp_Object_Type::Vector): {
|
||||||
|
fputs("[vector", file);
|
||||||
|
for (int i = 0; i < node->value.vector.length; ++i) {
|
||||||
|
fputs(" ", file);
|
||||||
|
print(node->value.vector.data+i);
|
||||||
|
}
|
||||||
|
fputs("]", file);
|
||||||
|
} break;
|
||||||
case (Lisp_Object_Type::Function): {
|
case (Lisp_Object_Type::Function): {
|
||||||
if (node->userType) {
|
if (node->userType) {
|
||||||
fprintf(file, "[%s]", Memory::get_c_str(node->userType->value.symbol.identifier));
|
fprintf(file, "[%s]", Memory::get_c_str(node->userType->value.symbol.identifier));
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ proc Lisp_Object_Type_to_string(Lisp_Object_Type type) -> const char* {
|
|||||||
case(Lisp_Object_Type::CFunction): return "C-function";
|
case(Lisp_Object_Type::CFunction): return "C-function";
|
||||||
case(Lisp_Object_Type::Continuation): return "continuation";
|
case(Lisp_Object_Type::Continuation): return "continuation";
|
||||||
case(Lisp_Object_Type::Pair): return "pair";
|
case(Lisp_Object_Type::Pair): return "pair";
|
||||||
|
case(Lisp_Object_Type::Vector): return "vector";
|
||||||
}
|
}
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -226,6 +226,50 @@ namespace Memory {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc allocate_vector(int size) -> Lisp_Object* {
|
||||||
|
/*
|
||||||
|
int object_memory_size;
|
||||||
|
Int_Array_List* free_spots_in_object_memory;
|
||||||
|
Lisp_Object* object_memory;
|
||||||
|
int next_index_in_object_memory = 0;
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (object_memory_size - next_index_in_object_memory < size) {
|
||||||
|
create_out_of_memory_error(
|
||||||
|
"There is not enough space in the lisp object "
|
||||||
|
"memory to allocate additional lisp objects. "
|
||||||
|
"Maybe try increasing the Memory size when "
|
||||||
|
"calling Memory::init()");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
int start = next_index_in_object_memory;
|
||||||
|
next_index_in_object_memory += size;
|
||||||
|
return object_memory+start;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc create_lisp_object_vector(int length, Lisp_Object* element_list) -> Lisp_Object* {
|
||||||
|
try assert_type(element_list, Lisp_Object_Type::Pair);
|
||||||
|
|
||||||
|
Lisp_Object* node;
|
||||||
|
try node = create_lisp_object();
|
||||||
|
set_type(node, Lisp_Object_Type::Vector);
|
||||||
|
|
||||||
|
node->value.vector.length = length;
|
||||||
|
try node->value.vector.data = allocate_vector(length);
|
||||||
|
|
||||||
|
Lisp_Object* head = element_list;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (head != Memory::nil) {
|
||||||
|
node->value.vector.data[i] = *head->value.pair.first;
|
||||||
|
head = head->value.pair.rest;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
proc get_or_create_lisp_object_symbol(String* identifier) -> Lisp_Object* {
|
proc get_or_create_lisp_object_symbol(String* identifier) -> Lisp_Object* {
|
||||||
// TODO(Felix): if we already have it stored somewhere then
|
// TODO(Felix): if we already have it stored somewhere then
|
||||||
// reuse it and dont create new one
|
// reuse it and dont create new one
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ enum struct Lisp_Object_Type {
|
|||||||
Number,
|
Number,
|
||||||
String,
|
String,
|
||||||
Pair,
|
Pair,
|
||||||
|
Vector,
|
||||||
Continuation,
|
Continuation,
|
||||||
// Pointer,
|
// Pointer,
|
||||||
// OwningPointer,
|
// OwningPointer,
|
||||||
@@ -76,6 +77,11 @@ struct Pair {
|
|||||||
Lisp_Object* rest;
|
Lisp_Object* rest;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Vector {
|
||||||
|
int length;
|
||||||
|
Lisp_Object* data;
|
||||||
|
};
|
||||||
|
|
||||||
struct Positional_Arguments {
|
struct Positional_Arguments {
|
||||||
Lisp_Object** symbols; // Array of Pointers to Lisp_Object<Symbol>
|
Lisp_Object** symbols; // Array of Pointers to Lisp_Object<Symbol>
|
||||||
int next_index;
|
int next_index;
|
||||||
@@ -87,6 +93,7 @@ struct Keyword_Arguments {
|
|||||||
// NOTE(Felix): values[i] will be nullptr if no defalut value was
|
// NOTE(Felix): values[i] will be nullptr if no defalut value was
|
||||||
// declared for key identifiers[i]
|
// declared for key identifiers[i]
|
||||||
Lisp_Object_Array_List* values;
|
Lisp_Object_Array_List* values;
|
||||||
|
// TODO(Felix): Why do we use a Array list here??
|
||||||
int next_index;
|
int next_index;
|
||||||
int length;
|
int length;
|
||||||
};
|
};
|
||||||
@@ -116,6 +123,7 @@ struct Lisp_Object {
|
|||||||
double number;
|
double number;
|
||||||
String* string;
|
String* string;
|
||||||
Pair pair;
|
Pair pair;
|
||||||
|
Vector vector;
|
||||||
Function function;
|
Function function;
|
||||||
cFunction* cFunction;
|
cFunction* cFunction;
|
||||||
Continuation continuation;
|
Continuation continuation;
|
||||||
|
|||||||
@@ -639,6 +639,8 @@ proc run_all_tests() -> bool {
|
|||||||
invoke_test_script("import_and_load");
|
invoke_test_script("import_and_load");
|
||||||
invoke_test_script("sicp");
|
invoke_test_script("sicp");
|
||||||
invoke_test_script("macro_expand");
|
invoke_test_script("macro_expand");
|
||||||
|
invoke_test_script("automata");
|
||||||
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user