Verified Commit f4ef461f authored by Camil Staps's avatar Camil Staps 🚀

Add documentation, use snake case for functions in ABC.Interpreter

parent 35f08c6d
Pipeline #18466 passed with stages
in 18 minutes and 3 seconds
......@@ -40,14 +40,14 @@ where
testThroughFile :: a !String !*World -> *(a, !*World)
testThroughFile graph fp w
# (Just graph_s,w) = serialize_for_interpretation optimise_addition "compiler.bc" w
# (Just graph_s,w) = serialize optimise_addition "compiler.bc" w
# (ok,f,w) = fopen fp FWriteData w
# (graph_s,f) = graphToFile graph_s f
# (graph_s,f) = graph_to_file graph_s f
# (_,w) = fclose f w
# (ok,f,w) = fopen fp FReadData w
# (Just graph_s,f) = graphFromFile f
# (Just graph_s,f) = graph_from_file f
# (_,w) = fclose f w
# (Just graph,w) = deserialize defaultDeserializationSettings graph_s (IF_WINDOWS "Compiler.exe" "compiler") w
......
definition module ABC.Interpreter
/**
* This module defines types and functions to use an interpreter for the ABC
* language for cross-platform (de)serialization of lazy expressions.
*
* Currently, functionality is limited to 64-bit platforms, because ABC code
* generated for 32-bit platforms is different.
*
* You need to set certain project options to use this library.
*
* When using cpm, set the following in your project file:
* - ByteCode: path for the main bytecode file (e.g. {Project}*app.bc)
* - CodeGen/GenerateByteCode: True
* - CodeGen/OptimiseABC: True (unless you suspect a bug in the ABC optimiser)
* - Link/StripByteCode: False (because we need symbols in the bytecode)
* - Link/GenerateSymbolTable: True (because we need symbols in the executable)
*
* In the Clean IDE, you can set these options in two panes:
* - Project options > Linker (GenerateSymbolTable)
* - Project options > Bytecode (all other options)
*
* There is currently no support for bytecode generation in clm.
*/
from StdMaybe import :: Maybe
/**
* This type describes settings used by the interpreter to deserialize
* expressions. You may also use {{`defaultDeserializationSettings`}}.
*/
:: DeserializationSettings =
{ heap_size :: !Int //* Heap size for the interpreter, in bytes (default: 2M)
, stack_size :: !Int //* Stack size for the interpreter, in bytes (default: 1M in total; 500k for A and 500k for BC stack)
......@@ -9,30 +36,98 @@ from StdMaybe import :: Maybe
defaultDeserializationSettings :: DeserializationSettings
/**
* A serialized expression.
* Use {{`graphToString`}} and {{`graphFromString`}} to convert this to and
* from strings, or use {{`graphToFile`}} and {{`graphFromFile`}} to read/write
* this from/to files.
*/
:: *SerializedGraph
/**
* This is an internal type.
*/
:: InterpretedExpression
/**
* This is an internal type.
*/
:: *InterpretationEnvironment
/**
* Serialize an expression for interpretation.
*
* @param The value to serialize.
* @param The path to the executable's bytecode (set by the `ByteCode` option in the project file).
* @result The result may be `Nothing` if the bytecode could not be parsed.
*/
serialize :: a !String !*World -> *(!Maybe SerializedGraph, !*World)
/**
* Deserialize an expression using the ABC interpreter.
* This version copies nodes as soon as they are in head normal form.
* Therefore, the result is only `Nothing` when pre-interpretation validation
* has failed (e.g., when the bytecode could not be parsed). If an
* interpretation error occurs this will most likely crash the host program.
* For more safety, see {{`deserialize_strict`}}.
*
* @param Settings for the interpreter.
* @param The graph to deserialize. Should be obtained using {{`serialize`}}.
* @param The path to the current executable (needed to resolve symbols when copying the result).
* @result The result may be `Nothing` when pre-interpretation validation has failed.
*/
deserialize :: !DeserializationSettings !SerializedGraph !String !*World -> *(!Maybe a, !*World)
/**
* This type represents several different run-time errors that may occur when
* deserializing an expression in strict mode (see {{`deserialize_strict`}}).
*/
:: DeserializedValue a
= DV_ParseError
//* The bytecode or serialized graph could not be parsed.
| DV_HeapFull
| DV_StackOverflow // On Windows, not all stack overflows can be caught
//* The interpreter had not enough heap to evaluate the expression.
| DV_StackOverflow
//* The interpreter had not enough stack to evaluate the expression.
//* NB: on Windows, not all stack overflows can be caught.
| DV_Halt
//* The ABC instruction `halt` was encountered.
| DV_IllegalInstruction
//* A forbidden (ccall, etc.) or unknown ABC instruction was encountered.
| DV_HostHeapFull
//* The heap of the host application has not enough space to copy the result.
| DV_Ok !a
//* Deserialization succeeded.
serialize_for_interpretation :: a !String !*World -> *(!Maybe SerializedGraph, !*World)
deserialize :: !DeserializationSettings !SerializedGraph !String !*World -> *(!Maybe a, !*World)
deserializeStrict :: !DeserializationSettings !SerializedGraph !String !*World
-> *(!DeserializedValue a, !*World)
/**
* Deserialize an expression using the ABC interpreter.
* This version evaluates the node to a normal form (unlike {{`deserialize`}},
* which copies the result as soon as it is in head normal form). This allows
* the interpreter to catch run-time errors (signaled in the
* {{`DeserializedValue`}} type), so you can use this function for sandboxing.
*
* @param Settings for the interpreter.
* @param The graph to deserialize. Should be obtained using {{`serialize`}}.
* @param The path to the current executable (needed to resolve symbols when copying the result).
*/
deserialize_strict :: !DeserializationSettings !SerializedGraph !String !*World -> *(!DeserializedValue a, !*World)
/**
* Deserialize the `Start` rule of a Clean application in bytecode format.
* This is essentially the same as {{`deserialize`}}, but it always interprets
* the start rule instead of a custom serialized graph.
*
* @param Settings for the interpreter.
* @param The path to the bytecode file to run (set by the `ByteCode` option in the project file).
* @param The path to the current executable (needed to resolve symbols when copying the result).
* @result The result may be `Nothing` when the bytecode cannot be parsed.
*/
get_start_rule_as_expression :: !DeserializationSettings !String !String !*World -> *(Maybe a, !*World)
graphToString :: !*SerializedGraph -> *(!.String, !*SerializedGraph)
graphFromString :: !String -> Maybe *SerializedGraph
graph_to_string :: !*SerializedGraph -> *(!.String, !*SerializedGraph)
graph_from_string :: !String -> Maybe *SerializedGraph
graphToFile :: !*SerializedGraph !*File -> *(!*SerializedGraph, !*File)
graphFromFile :: !*File -> *(!Maybe *SerializedGraph, !*File)
graph_to_file :: !*SerializedGraph !*File -> *(!*SerializedGraph, !*File)
graph_from_file :: !*File -> *(!Maybe *SerializedGraph, !*File)
......@@ -40,8 +40,8 @@ defaultDeserializationSettings =
, ie_snodes :: !*{a}
}
serialize_for_interpretation :: a !String !*World -> *(!Maybe SerializedGraph, !*World)
serialize_for_interpretation graph bcfile w
serialize :: a !String !*World -> *(!Maybe SerializedGraph, !*World)
serialize graph bcfile w
# (graph,descs,mods) = copy_to_string_with_names graph
# (bytecode,w) = readFile bcfile w
......@@ -77,9 +77,8 @@ where
deserialize :: !DeserializationSettings !SerializedGraph !String !*World -> *(!Maybe a, !*World)
deserialize dsets graph thisexe w = deserialize` False dsets graph thisexe w
deserializeStrict :: !DeserializationSettings !SerializedGraph !String !*World
-> *(!DeserializedValue a, !*World)
deserializeStrict dsets graph thisexe w = case deserialize` True dsets graph thisexe w of
deserialize_strict :: !DeserializationSettings !SerializedGraph !String !*World -> *(!DeserializedValue a, !*World)
deserialize_strict dsets graph thisexe w = case deserialize` True dsets graph thisexe w of
(Nothing,w) -> (DV_ParseError,w)
(Just v,w) -> (v,w)
......@@ -161,7 +160,7 @@ where
PREFIX_D = 4
get_start_rule_as_expression :: !DeserializationSettings !String !String !*World -> *(Maybe a, !*World)
get_start_rule_as_expression dsets prog filename w
get_start_rule_as_expression dsets filename prog w
# (syms,w) = accFiles (read_symbols prog) w
# (bc,w) = readFile filename w
| isNothing bc = (Nothing, w)
......@@ -210,8 +209,8 @@ make_finalizer ie_settings = code {
pushI 0
}
graphToString :: !*SerializedGraph -> *(!.String, !*SerializedGraph)
graphToString g=:{graph,descinfo,modules,bytecode}
graph_to_string :: !*SerializedGraph -> *(!.String, !*SerializedGraph)
graph_to_string g=:{graph,descinfo,modules,bytecode}
# (graph_cpy,graph,graph_size) = copy graph
# g & graph = graph
# string_size = sum
......@@ -266,8 +265,8 @@ where
# (i,s) = write arr.[n] i s
= writeArray write (n+1) arr i s
graphFromString :: !String -> Maybe *SerializedGraph
graphFromString s = read 0 s
graph_from_string :: !String -> Maybe *SerializedGraph
graph_from_string s = read 0 s
where
read :: !Int !String -> Maybe *SerializedGraph
read i s
......@@ -338,17 +337,17 @@ where
# (i,xs) = readArray read (len-1) i s
= (i,[x:xs])
graphToFile :: !*SerializedGraph !*File -> *(!*SerializedGraph, !*File)
graphToFile g f
# (s,g) = graphToString g
graph_to_file :: !*SerializedGraph !*File -> *(!*SerializedGraph, !*File)
graph_to_file g f
# (s,g) = graph_to_string g
# f = f <<< size s <<< s
= (g,f)
graphFromFile :: !*File -> *(!Maybe *SerializedGraph, !*File)
graphFromFile f
graph_from_file :: !*File -> *(!Maybe *SerializedGraph, !*File)
graph_from_file f
# (_,size,f) = freadi f
# (s,f) = freads f size
# g = graphFromString s
# g = graph_from_string s
= (g,f)
malloc :: !Int -> Pointer
......
definition module ABC.Interpreter.Internal
/**
* This module defines internal functions used by the ABC interpreter library
* (see {{`ABC.Interpreter`}}). It is not meant to be included directly.
*/
import ABC.Interpreter
add_shared_node :: !Int !*{a} a -> *(!Int, !*{a}, !Int)
......
definition module ABC.Interpreter.Util
/**
* This module defines internal functions used by the ABC interpreter library
* (see {{`ABC.Interpreter`}}). It is not meant to be included directly.
*/
from _SystemArray import class Array
from StdMaybe import :: Maybe
from symbols_in_program import :: Symbol
......
......@@ -12,13 +12,13 @@ import ABC.Interpreter
// the first 100 elements.
import StdEnum,StdFunc
//Start w
//# (Just primes,w) = get_start_rule_as_expression (IF_WINDOWS "CodeSharing.exe" "CodeSharing") "infprimes.bc" w
//# (Just primes,w) = get_start_rule_as_expression "infprimes.bc" (IF_WINDOWS "CodeSharing.exe" "CodeSharing") w
//= last (iter 10 reverse [0..last (reverse (reverse (take 2000 primes)))])
// Example: get a function from a bytecode file and apply it
Start w
# (Just (intsquare,sub5,sub3_10,sumints,rev,foldr,ap1,ap3,map,repeat,internal_types),w)
= get_start_rule_as_expression defaultDeserializationSettings (IF_WINDOWS "CodeSharing.exe" "CodeSharing") "functions.bc" w
= get_start_rule_as_expression defaultDeserializationSettings "functions.bc" (IF_WINDOWS "CodeSharing.exe" "CodeSharing") w
= (use intsquare sub5 sub3_10 sumints rev foldr ap1 ap3 map repeat, internal_types)
where
use ::
......
......@@ -21,11 +21,11 @@ where
DV_HostHeapFull -> DV_HostHeapFull
Start w
# (graph,w) = serialize_for_interpretation graph "GraphTest.bc" w
# (graph,w) = serialize graph "GraphTest.bc" w
# graph = case graph of
Nothing -> abort "Could not serialize the graph; is GraphTest.bc up to date?\n"
Just g -> g
# (DV_Ok (intsquare,sub5,sub3_10,sumints,rev,foldr,ap1,ap3,map,reverse_string,reverse_array,reverse_boxed_array,reverse_recarr,recarr,toInt_rec,repeat,sumtup,createarray),w) = deserializeStrict defaultDeserializationSettings graph (IF_WINDOWS "GraphTest.exe" "GraphTest") w
# (DV_Ok (intsquare,sub5,sub3_10,sumints,rev,foldr,ap1,ap3,map,reverse_string,reverse_array,reverse_boxed_array,reverse_recarr,recarr,toInt_rec,repeat,sumtup,createarray),w) = deserialize_strict defaultDeserializationSettings graph (IF_WINDOWS "GraphTest.exe" "GraphTest") w
= use intsquare sub5 sub3_10 sumints rev foldr ap1 ap3 map reverse_string reverse_array reverse_boxed_array reverse_recarr recarr toInt_rec repeat sumtup createarray
where
use ::
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment