Coverage report: /development/source/library/org/datagraph/spocq-shard/src/core/ssl/ssl-primitives.lisp
| Kind | Covered | All | % |
| expression | 77 | 223 | 34.5 |
| branch | 0 | 14 | 0.0 |
Key
Not instrumented
Conditionalized out
Executed
Not executed
Both branches taken
One branch taken
Neither branch taken
1
;;; -*- Mode: lisp; Syntax: ansi-common-lisp; Base: 10; Package: org.datagraph.spocq.implementation; -*-
3
(in-package :org.datagraph.spocq.implementation)
5
(:documentation "run-time implementation for the SSL machine."
6
"This implements the internal state functions and the primitive word functions which operator on the code and
7
stack state to effect script execution.
9
The run-time state comprises three objects
11
the stack of evaluated values staged for combination as function arguments
14
the sequence of expressions and words (functions) to be executed
15
represented as a list of (possibly nested) values
17
the current evaluation environment binds symbols to functions an values
18
represented as an association list
20
each evaluation rebinds selected state components dynamically and repeats operations from
21
the code sequence until the sequence is exhausted, at which point the evaluation is complete and control
22
returns to the caller. the stack then retains any any result(s). the modes execution interfaces exist
23
ssl:call : contrains the argument to be a function; calls the function without rebinding
24
ssl:evaluate : constrains the argument to be a list; rebinds just the code sequence
25
ssl:run : accepts and rebinds all state components; given a code designator, retrieve and/or compile
28
in general, any object is treated as first-class, that is, permitted in code, on the stack - and as such,
29
passed and returned, as well as bound in the environment.
30
at the same time, particular object classes involve special handling
31
boolean : logical truth distinguishes not only t and nil, but 0, "", unbound variable markers and
32
empty solution fields as false (see ssl:true)
33
word : a specialized generic function type captures the intended result arity from the definition in
34
order to transfer the results to the run-time stack (in the ame order as if appearing in code)
35
solution-field : handled as the argument to boolean tests and to iteration control operators
37
the implementation resides on three levels
38
%%- operators accept values and return them
39
%- operators work the the %%- level operators to manipulate the three state objects
40
word operators again accept and returns values. the arguments are staged by the %- operators from
41
run-time state and results are placed back into the run-time state by the invoking %- opeator uon return
45
(defclass ssl:word (sslr:function)
47
(:metaclass c2mop:funcallable-standard-class))
50
(defmacro ssl:defword (name lambda-list &rest options)
51
(macroexpand-defword name lambda-list options))
54
(eval-when (:compile-toplevel :load-toplevel :execute)
55
(defun macroexpand-defword (name lambda-list options)
56
(let* ((values-option (assoc :values options))
57
(keywords (load-time-value (cons '&code lambda-list-keywords)))
58
(after-required (member-if #'(lambda (term) (member term keywords)) lambda-list))
59
(required-parameters (ldiff lambda-list after-required))
60
(code-parameters (let* ((codes (member '&code after-required))
61
(before-codes (ldiff after-required codes))
62
(after-codes (member-if #'(lambda (term) (member term keywords)) (rest codes))))
64
(setf codes (ldiff codes after-codes))
65
(setf lambda-list (append required-parameters (rest codes)
68
(rest (ldiff codes after-codes)))))
69
(keyword-parameters (let ((keys (member '&key lambda-list)))
70
(rest (ldiff keys (member-if #'(lambda (term) (member term keywords)) (rest keys))))))
71
(class-option (assoc :generic-function-class options))
72
(signature `(sslr:make-function-signature
73
:required-parameters ',required-parameters
74
:keyword-parameters ',(loop for element in keyword-parameters
75
collect (if (consp element) (caar element) (intern (symbol-name element) :keyword)))
76
:code-parameters ',code-parameters
77
:values ',(if values-option (rest values-option) '(t)))))
79
(setf options (remove values-option options))
81
(setf options (remove class-option options))
82
(setf class-option '(:generic-function-class ssl:word)))
83
`(let ((word (defgeneric ,name ,lambda-list ,@options ,class-option)))
84
(sslr::setf-function-signature ,signature word)
89
;;; stack side-effect operations :
90
;;; always reconstruct the stack rather than side-effecting it in case
91
;;; something else has a binding...
93
(ssl:defword ssl:bind (variable value)
95
"Introduce a binding for the pair on the stack into the current environment")
97
(:method ((variable symbol) (value t))
98
(sslr:bind variable value)
102
(ssl:defword ssl:cons (first rest)
103
(:method ((first t) (rest t))
107
(ssl:defword ssl:dup (top)
109
(values value value))
112
(ssl:defword ssl:drop (top)
117
(ssl:defword ssl:first (list)
118
(:method ((value list))
122
(ssl:defword ssl:nip (next top)
123
(:method ((next t) (top t))
127
(ssl:defword ssl:rest (list)
128
(:method ((value list))
132
(ssl:defword ssl:set (variable value)
134
(:method ((variable symbol) (value t))
135
(sslr:set variable value)
139
(ssl:defword ssl:swap (next top)
140
(:method ((next t) (top t))
145
;;; environment operations :
147
(ssl:defword ssl:code ()
152
(ssl:defword ssl:environment ()
159
(ssl:defword ssl::stack ()
165
;;; control-flow operations :
167
(ssl:defword ssl:call (function)
168
(:documentation "Invoke the given function, return with stack/code/environment as modified.")
170
(:method ((function t))
171
(sslr:call function)))
173
(ssl:defword ssl:eval (object)
174
(:documentation "Evaluate the given object. Given a code list, execute it, Given anything else,
175
determine its value return with stack/environment as
176
modified, but restore the code sequence.")
178
(:method ((object t))
181
(ssl:defword ssl:run (code)
183
(:method ((code list))
187
(ssl:defword ssl:execute (stack code environment)
188
(:documentation "Execute a stack/code/environment combination for side-effect.
189
Invoke the internal run-time operator which restores the original stack/code/combination upon completion
190
Permit code which locates the code sequence with an iri or a local string in addition to
191
representing the code directly as a list. Given location, load the graph under authorization constraints.")
194
(:method (stack (code string) environment)
195
(ssl:execute stack (load-ssl-graph code) environment))
196
(:method (stack (code spocq:iri) environment)
197
(ssl:execute stack (load-ssl-graph code) environment))
199
(:method (stack (code list) environment)
200
(sslr:execute stack code environment)))
204
(ssl:defword ssl:and ()
208
(loop until (null sslr:*code*)
209
for result = (progn (sslr:eval (sslr:pop-code))
211
while (sslr:true result)
212
finally (return result))
215
(ssl:defword ssl:if (predicate-value &code consequent alternative)
217
(:method (predicate-value consequent alternative)
218
(sslr:eval (if (sslr:true predicate-value) consequent alternative))
221
(ssl:defword ssl:not (value)
224
(not (sslr:true value))))
226
(ssl:defword ssl:or ()
229
(loop until (null sslr:*code*)
230
for result = (progn (sslr:eval (sslr:pop-code))
232
until (sslr:true result)
233
finally (return result))))
235
(ssl:defword ssl:true (value)
240
(ssl:defword ssl:while (&code predicate-form consequent)
242
(:method (predicate-form consequent)
243
(loop while (sslr:true (progn (sslr:eval predicate-form) (sslr:pop)))
244
do (sslr:eval consequent))
248
(ssl:defword ssl:continuation ()
250
"Capture the continuation as a function and push it on the stack.
251
When called, the operator will run starting from the current state and place
252
a single result on the stack upon completion.")
257
(ssl:defword ssl:continue (continuation)
258
(:method ((continuation function))
259
(funcall continuation))
263
(ssl:defword ssl:word (code)
265
"Combine the code at the top of the stack with the current environment to construct
266
a new function and push it onto the stack")
268
(:method ((code list))
269
(sslr:closure code)))
272
(ssl:defword ssl:thread (code)
273
(:documentation "start a new thread with the tos code sequence")
274
(:method ((code list))
275
(bt:make-thread (sslr:closure code)))
279
(macrolet ((defprimitive (base-operator signature &optional (values '(t)))
280
(let ((ssl-name (intern (symbol-name base-operator) :ssl))
281
(parameters (loop for parameter in signature
282
collect (etypecase parameter
284
(cons (first parameter))))))
285
(export ssl-name :ssl)
286
`(ssl:defword ,ssl-name ,parameters
288
(,base-operator ,@parameters))
290
(defprimitives (base-operators signature &optional (values '(t)))
291
`(progn ,@(loop for operator in base-operators
292
collect `(defprimitive ,operator ,signature ,values)))))
293
(defprimitives (+ - / * = < > <= >= /=) ((arg1 number) (arg2 number)))
294
(defprimitives (minusp plusp zerop not null) ((arg number)))
295
(defprimitives (decf incf) ((arg number)))
299
(ssl:defword ssl::request-stream ()
300
(:method () (processor-request-content-location *request-processor*))
302
(ssl:defword ssl::response-stream ()
303
(:method () (processor-response-content-location *request-processor*))
305
(ssl:defword ssl::request-content-type ()
306
(:method () (processor-request-content-type *request-processor*))
307
(:values mime:mime-type))
308
(ssl:defword ssl::response-content-type ()
309
(:method () (processor-response-content-type *request-processor*))
310
(:values mime:mime-type))
311
(ssl:defword ssl::request-repository ()
312
(:method () (task-repository *task*))
313
(:values repository))
318
(ssl:defword ssl::print (value)
324
(ssl:defword ssl::print-stack ()
330
(ssl:defword ssl::print-code ()
337
;;; more explicit code
338
'(("select * where { {?s ?p ?o} union { graph ?g {?s ?p ?o}} }" :location
339
mime:application/sparql-query :media-type <ssl:Decode>
340
"jhacker/test" :dataset <http://www.w3.org/ns/entailment/D> :method <ssl:Bind>
342
mime:application/sparql-results+json :media-type
343
*trace-output* :location <ssl:Encode> )