Verified Commit 158b02bf authored by Camil Staps's avatar Camil Staps 🚀

Add ABC instructions (#137)

parent a2c80b23
definition module BuiltinABCInstructions
from CloogleDB import :: ABCInstructionEntry
builtin_abc_instructions :: [ABCInstructionEntry]
implementation module BuiltinABCInstructions
import StdMisc
import StdOverloaded
import Cloogle
import CloogleDB
builtin_abc_instructions :: [ABCInstructionEntry]
builtin_abc_instructions =
[ i_ccall
, i_halt
, i_no_op
: [{zero & aie_instruction=i} \\ i <- other_instructions]
]
instance zero ABCInstructionEntry
where
zero =
{ aie_instruction = undef
, aie_arguments = []
, aie_description = "There is no documentation for this ABC instruction yet."
}
i_ccall :: ABCInstructionEntry
i_ccall =
{ zero
& aie_instruction = "ccall"
, aie_arguments = [ABCArgument ABCTypeLabel False, ABCArgument ABCTypeString False]
, aie_description = "Calls a C function."
}
i_halt :: ABCInstructionEntry
i_halt =
{ zero
& aie_instruction = "halt"
, aie_description = "Terminates the program immediately."
}
i_no_op :: ABCInstructionEntry
i_no_op =
{ zero
& aie_instruction = "no_op"
, aie_description = "Do nothing. This is for example useful in the `cast` function:\n\n```clean\ncast :: .a -> .b\ncast _ = code {\n\tno_op\n}\n```"
}
/**
* Instructions without documentation yet
*/
other_instructions :: [String]
other_instructions =
[ "absR"
, "acosR"
, "add_args"
, "addI"
, "addLU"
, "addR"
, "andB"
, "and%"
, "asinR"
, "atanR"
, "build"
, "buildB"
, "buildC"
, "buildI"
, "buildR"
, "buildAC"
, "buildB_b"
, "buildC_b"
, "buildF_b"
, "buildI_b"
, "buildR_b"
, "buildh"
, "build_r"
, "build_u"
, "catS"
, "call"
, "centry"
, "cmpS"
, "ceilingR"
, "CtoAC"
, "copy_graph"
, "cosR"
, "code_channelP"
, "create"
, "create_array"
, "create_array_"
, "create_channel"
, "currentP"
, "CtoI"
, "decI"
, "del_args"
, "divI"
, "divLU"
, "divR"
, "divU"
, "entierR"
, "eqB"
, "eqB_a"
, "eqB_b"
, "eqC"
, "eqC_a"
, "eqC_b"
, "eqD_b"
, "eqI"
, "eqI_a"
, "eqI_b"
, "eqR"
, "eqR_a"
, "eqR_b"
, "eqAC_a"
, "eq_desc"
, "eq_desc_b"
, "eq_nulldesc"
, "eq_symbol"
, "exit_false"
, "expR"
, "fill"
, "fill1"
, "fill2"
, "fill3"
, "fill1_r"
, "fill2_r"
, "fill3_r"
, "fillcaf"
, "fillcp"
, "fillcp_u"
, "fill_u"
, "fillh"
, "fillB"
, "fillB_b"
, "fillC"
, "fillC_b"
, "fillF_b"
, "fillI"
, "fillI_b"
, "fillR"
, "fillR_b"
, "fill_a"
, "fill_r"
, "floordivI"
, "getWL"
, "get_desc_arity"
, "get_desc_flags_b"
, "get_desc0_number"
, "get_node_arity"
, "gtC"
, "gtI"
, "gtR"
, "gtU"
, "in"
, "incI"
, "instruction"
, "is_record"
, "ItoC"
, "ItoP"
, "ItoR"
, "jmp"
, "jmp_ap"
, "jmp_ap_upd"
, "jmp_upd"
, "jmp_eval"
, "jmp_eval_upd"
, "jmp_false"
, "jmp_not_eqZ"
, "jmp_true"
, "jrsr"
, "jsr"
, "jsr_ap"
, "jsr_eval"
, "lnR"
, "load_i"
, "load_si16"
, "load_si32"
, "load_ui8"
, "log10R"
, "ltC"
, "ltI"
, "ltR"
, "ltU"
, "modI"
, "mulI"
, "mulR"
, "mulUUL"
, "negI"
, "negR"
, "new_ext_reducer"
, "new_int_reducer"
, "newP"
, "notB"
, "not%"
, "orB"
, "or%"
, "out"
, "pop_a"
, "pop_b"
, "powR"
, "print"
, "printD"
, "print_char"
, "print_int"
, "print_real"
, "print_r_arg"
, "print_sc"
, "print_symbol"
, "print_symbol_sc"
, "pushcaf"
, "push_finalizers"
, "pushA_a"
, "pushB"
, "pushB_a"
, "pushC"
, "pushC_a"
, "pushD"
, "pushD_a"
, "pushF_a"
, "pushI"
, "pushI_a"
, "pushL"
, "pushLc"
, "pushR"
, "pushR_a"
, "pushzs"
, "push_a"
, "push_b"
, "push_a_b"
, "push_arg"
, "push_arg_b"
, "push_args"
, "push_args_u"
, "push_array"
, "push_arraysize"
, "push_b_a"
, "push_node"
, "push_node_u"
, "push_a_r_args"
, "push_t_r_a"
, "push_t_r_args"
, "push_r_args"
, "push_r_args_a"
, "push_r_args_b"
, "push_r_args_u"
, "push_r_arg_D"
, "push_r_arg_t"
, "push_r_arg_u"
, "push_wl_args"
, "pushZ"
, "pushZR"
, "putWL"
, "randomP"
, "release"
, "remI"
, "remU"
, "replace"
, "repl_arg"
, "repl_args"
, "repl_args_b"
, "repl_r_args"
, "repl_r_args_a"
, "rotl%"
, "rotr%"
, "rtn"
, "RtoI"
, "select"
, "send_graph"
, "send_request"
, "set_continue"
, "set_defer"
, "set_entry"
, "set_finalizers"
, "setwait"
, "shiftl%"
, "shiftr%"
, "shiftrU"
, "sinR"
, "sincosR"
, "sliceS"
, "sqrtR"
, "stop_reducer"
, "subI"
, "subLU"
, "addIo"
, "mulIo"
, "subIo"
, "subR"
, "suspend"
, "tanR"
, "testcaf"
, "truncateR"
, "update_a"
, "updatepop_a"
, "update_b"
, "updatepop_b"
, "updateS"
, "update"
, "xor%"
, ".algtype"
, ".caf"
, ".code"
, ".comp"
, ".a"
, ".d"
, ".depend"
, ".desc"
, ".desc0"
, ".descn"
, ".descexp"
, ".descs"
, ".end"
, ".endinfo"
, ".export"
, ".keep"
, ".inline"
, ".impdesc"
, ".implab"
, ".implib"
, ".impmod"
, ".impobj"
, ".module"
, ".n"
, ".nu"
, ".newlocallabel"
, ".n_string"
, ".o"
, ".pb"
, ".pd"
, ".pe"
, ".pl"
, ".pld"
, ".pn"
, ".pt"
, ".record"
, ".start"
, ".string"
]
definition module BuiltinSyntax
from CloogleDB import :: SyntaxEntry
builtin_syntax :: [SyntaxEntry]
implementation module BuiltinSyntax
import StdList
from Data.Func import $
import Data.Maybe
import Text
import Cloogle
import CloogleDB
import Builtins
builtin_syntax :: [SyntaxEntry]
builtin_syntax =
[ bs_case
, bs_class
, bs_code
, bs_define_constant
, bs_define_graph
, bs_dotdot
, bs_exists
, bs_forall
, bs_generic
, bs_import
, bs_infix
, bs_instance
, bs_lambda
, bs_layout_rule
, bs_let
, bs_let_before
, bs_list_expressions
, bs_macro
, bs_module
, bs_newtype
, bs_overloaded_type_variable
, bs_otherwise
, bs_pattern_named
, bs_selection_array
, bs_selection_array_unique
, bs_selection_record
, bs_selection_record_unique
, bs_strict
, bs_synonym
, bs_synonym_abstract
, bs_update_array
, bs_update_record
, bs_where_class
, bs_where_instance
, bs_where_local
, bs_with
, bs_zf
]
EX :: String String -> SyntaxExample
EX t c = {example=c, cleanjs_type=t, cleanjs_start=Nothing}
EXs :: String String String -> SyntaxExample
EXs t s c = {example=c, cleanjs_type=t, cleanjs_start=Just s}
bs_case =
{ syntax_title = "case expression"
, syntax_patterns = ["case", "of", "case of"]
, syntax_code = ["case ... of ..."]
, syntax_description = "Pattern match on an expression and do something depending on the alternative of the matching pattern."
, syntax_doc_locations = [CLR 5 "3.4.2" "_Toc311798001"]
, syntax_examples =
[ EXs "Function" "macro" "isJust m = case m of\n\tJust _ -> True\n\t_ -> False"
]
}
bs_class =
{ syntax_title = "class"
, syntax_patterns = ["class"]
, syntax_code =
[ "class ... ... :: ..."
, "class ... ... where ..."
]
, syntax_description =
"Classes are (sets of) overloaded functions. For classes with only one member function, a simplified syntax exists.\n\n" +
"Types can instantiate classes with the {{`instance`}} keyword."
, syntax_doc_locations = [CLR 8 "6.1" "_Toc311798056"]
, syntax_examples = map (EX "ClassDef")
[ "class zero a :: a // one member" // TODO highlighting
, "class Text s // multiple members\nwhere\n\ttextSize :: !s -> Int\n\tconcat :: ![s] -> s\n\t// ..." // TODO highlighting
]
}
bs_code =
{ syntax_title = "ABC code"
, syntax_patterns = ["code", "inline", "code inline"]
, syntax_code = ["... = code [inline] { ... }"]
, syntax_description =
"A code block with raw ABC instructions, which can be used for primitive functions like integer addition, for linking with C, bypassing the type system... welcome down the rabbit hole!\n\n" +
"When `inline` is used, the function will be inlined when applied in a strict context."
, syntax_doc_locations = [CLR 13 "11.2" "_Toc311798115"]
, syntax_examples = map (EX "Function") // TODO highlighting
[ "add :: !Int !Int -> Int // Primitive function\nadd a b = code inline {\n\taddI\n}"
, "sleep :: !Int !*World -> *(!Int, !*World) // Linking with C\nsleep n w = code {\n\tccall sleep \"I:I:A\"\n}"
, "cast :: !.a -> .b // Bypassing the type system\ncast _ = code {\n\tno_op\n}"
]
}
bs_define_constant =
{ syntax_title = "graph definition"
, syntax_patterns = ["=:"]
, syntax_code = ["... =: ..."]
, syntax_description =
"Defining constants with `=:` at the top level makes sure they are shared through out the program; hence, they are evaluated only once.\n\n" +
"This is the default understanding of `=` in local scope.\n\n" +
"The inverse is {{`=>`}}, which defines an identifier to be a constant function."
, syntax_doc_locations = [CLR 5 "3.6" "_Toc311798007"]
, syntax_examples = [EXs "Function" "macro" "mylist =: [1..10000]"]
}
bs_define_graph =
{ syntax_title = "constant function definition"
, syntax_patterns = ["=>"]
, syntax_code = ["... => ..."]
, syntax_description =
"Defining constants with `=>` at the top level makes sure they are interpreted as constant functions; hence, they are evaluated every time they are needed.\n\n" +
"This is the default understanding of `=` in global scope.\n\n" +
"The inverse is {{`=:`}}, which defines an identifier to be a graph."
, syntax_doc_locations = [CLR 5 "3.6" "_Toc311798007"]
, syntax_examples = [EXs "Function" "macro" "mylist => [1..10000]"]
}
bs_dotdot =
{ syntax_title = "dotdot expression"
, syntax_patterns = ["[\\e..]", "[\\e..\e]", "[\\e,\\e..]", "[[\\e,\\e..\\e]", "dotdot", "dot-dot", ".."]
, syntax_code = ["[i..]", "[i..k]", "[i,j..]", "[i,j..k]"]
, syntax_description =
"A shorthand for lists of enumerable types.\n\n" +
"To use these expressions, you must import {{`StdEnum`}}. The underlying functions are defined in {{`_SystemEnum`}}."
, syntax_doc_locations = [CLR 6 "4.2.1" "_Toc311798023"]
, syntax_examples = map (EXs "Function" "macro")
[ "xs = [0..] // 0, 1, 2, 3, ..."
, "xs = [0,2..] // 0, 2, 4, 6, ..."
, "xs = [0..10] // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10"
, "xs = [0,2..10] // 0, 2, 4, 6, 8, 10"
]
}
bs_exists =
{ syntax_title = "existential quantifier"
, syntax_patterns = ["E", "E.*"]
, syntax_code = [":: ... = E. ...: ..."]
, syntax_description = "Existential quantifiers make it possible to define (recursive) objects of the same type with different types of content."
, syntax_doc_locations = [CLR 7 "5.1.3" "_Toc311798042"]
, syntax_examples = [EX "Function" ":: List = E.e: Cons e List | Nil\nStart = Cons 5 (Cons 'a' (Cons \"abc\" Nil))"] // TODO highlighting
}
bs_forall =
{ syntax_title = "universal quantifier"
, syntax_patterns = ["A", "A.*"]
, syntax_code = ["A. ...:"]
, syntax_description = "Explicitly marks polymorphic type variables. Clean does not yet allow universal quantifiers on the topmost level."
, syntax_doc_locations = [CLR 5 "3.7.4" "_Toc311798013"]
, syntax_examples =
[ EX "Function" "hd :: A.a: [a] -> a // Not yet allowed: A. on the topmost level"
, EX "Function" "h :: (A.a: [a] -> Int) -> Int // The quantifier is needed to apply the function to both a [Int] and a [Char]\nh f = f [1..100] + f ['a'..'z']"
, EX "TypeDef" ":: T = C (A.a: a -> a) // In a type"
]
}
bs_generic =
{ syntax_title = "generic function definition"
, syntax_patterns = ["generic", "derive", "of", "{|*|}"] // This * matches everything, which is intentional
, syntax_code = ["generic ... ... :: ...", "derive ... ..."]
, syntax_description = "With generics, a function can be defined once and derived for (almost) all possible types, to avoid very similar code snippets."
, syntax_doc_locations = [CLR 9 "7.2" "_Toc311798069"]
, syntax_examples =
[ EX "Function" "generic gEq a :: !a !a -> Bool // The type of a generic function"
, EXs "Function" "macro" $ "gEq{|Int|} x y = x == y // Implementation of a generic\n" +
"gEq{|PAIR|} fx fy (PAIR x1 y1) (PAIR x2 y2) = fx x1 x2 && fy y1 y2" // TODO highlighting
, EX "Function" "derive gEq [] // Deriving the gEq generic for type []"
, EXs "Function" "macro" "gConsName{|CONS of d|} _ = d.gcd_name // Using type information"
]
}
bs_import =
{ syntax_title = "imports"
, syntax_patterns = ["import", "from", "qualified", "as", "=>", "code", "library"]
, syntax_code =
[ "import [qualified] ... [as ...]"
, "from ... import ..."
, "import ... => qualified ..."
, "import code from [library] ..."
]
, syntax_description =
"Imports code from other modules.\n\n" +
"With the `from` keyword, one can achieve more granularity.\n\n" +
"In case of name clashes, `qualified` can be used (undocumented).\n\n" +
"Moreover, you can import from object files or windows DLLs."
, syntax_doc_locations = [CLR 4 "2.5" "_Toc311797991"]
, syntax_examples = map (EX "Function")
[ "import StdEnv // Import all code from the StdEnv definition module"
, "from StdFunc import o // Import only the o function from StdFunc"
, "import qualified Data.Map // Import Data.Map such that functions are available as e.g. 'Data.Map'.get."
, "import qualified Data.Map as M // Import Data.Map such that functions are available as e.g. 'M'.get."
, "import Control.Monad => qualified join // Import all code from Control.Monad except for join. join is imported qualified"
, "import code from \"tty.\" // Import functions from the object file matching 'Clean System Files/tty.*'"
, "import code from library \"msvcrt\" // Import functions from linked DLLs according to the msvcrt file in Clean System Files.\n" +
" // The file should start with the DLL name (e.g. msvcrt) and followed by one line per function you want to link."
]
}
bs_infix =
{ syntax_title = "infix operator"
, syntax_patterns = ["infix", "infixl", "infixr"]
, syntax_code = ["infix[l,r] [...]"]
, syntax_description =
"Defines a function with arity 2 that can be used in infix position.\n\n" +
"The following number, if any, determines the precedence.\n\n" +
"`infixl` and `infixr` indicate associativity."
, syntax_doc_locations = [CLR 5 "3.7.2" "_Toc311798011"]
, syntax_examples =
[ EX "Function" "(bitor) infixl 6 :: !Int !Int -> Int // Left-associative infix function with precedence 6"
, EXs "Function" "macro" "(o) infixr 9 // Infix macro\n(o) f g :== \\x -> f (g x)"
, EX "TypeDef" ":: MyType = (:+:) infixl 6 Int Int // Infix data constructor, can be used as (5 :+: 10)"
]
}
bs_instance =
{ syntax_title = "instance"
, syntax_patterns = ["instance"]
, syntax_code = ["instance ... ... where ..."]
, syntax_description = "Defines an instantiation of a {{class}} for a type."
, syntax_doc_locations = [CLR 8 "6.1" "_Toc311798056"]
, syntax_examples = map (EX "Function")
[ "instance zero Int\nwhere\n\tzero = 0"
, "instance zero Real\nwhere\n\tzero = 0.0"
]
}
bs_lambda =
{ syntax_title = "lambda abstraction"
, syntax_patterns = ["lambda", "\\*", "->", "."]
, syntax_code = ["\\... -> ...", "\\... . ...", "\\... = ..."]
, syntax_description = "An anonymous, inline function."
, syntax_doc_locations = [CLR 5 "3.4.1" "_Toc311798000"]
, syntax_examples = map (EXs "Function" "macro")
[ "(o) f g = \\x -> f (g x) // Simple lambda expression"
, "swapall = map (\\(x,y) -> (y,x)) // Pattern matching in lambda arguments"
, "mul = \\x y -> x * y // Multiple arguments (of course, it would be better to write `mul x y = x * y` or `mul = (*)`)"
]
}
bs_layout_rule =
{ syntax_title = "layout rule"
, syntax_patterns = [";", "{", "}"]
, syntax_code = ["...;", "{ ... }"]
, syntax_description =
"Most Clean programs are written using the layout rule, which means that scopes are indicated with indent levels." +
"The layout sensitive mode can be turned off by adding a semicolon `;` at the end of the {{module}} line." +
"Then, scopes have to be indicated with `{ ... }` and definitions have to end with `;`."
, syntax_doc_locations = [CLR 4 "2.3.3" "_Toc311797989"]
, syntax_examples = [EX "Module" $
"module test;\n" +
"import StdEnv;\n" +
"Start :: [(Int,Int)];\n" +
"Start = [(x,y) \\\\ x <- odds, y <- evens];\n" +
"where\n" +
"{\n" +
"\todds = [1,3..9];\n" +
"\tevens = [0,2..8];\n" +
"}"]
}
bs_let =
{ syntax_title = "let expression"
, syntax_patterns = ["let", "in", "let in"]
, syntax_code = ["let ... in ..."]
, syntax_description = "An expression that introduces new scope."
, syntax_doc_locations = [CLR 5 "3.5.1" "_Toc311798003"]
, syntax_examples =
[ EXs "Function" "macro" "fac n = let fs = [1:1:[(fs!!(i-1)) + (fs!!(i-2)) \\ i <- [2..]]] in fs !! n"
, EXs "Function" "macrorhs" "let // Multi-line let expressions\n\tfunction args = body\n\tselector = expr\n\t// ...\nin expression"