├── .devcontainer ├── nix.conf ├── profile.sh ├── Dockerfile ├── docker │ └── devcontainer.json └── podman │ └── devcontainer.json ├── bin ├── hog │ ├── boot │ │ ├── bootgen.sh │ │ └── gen │ │ │ ├── boot.H │ │ │ └── boot.C │ ├── path.H │ ├── out.H │ ├── recovery.H │ ├── network.H │ ├── local.H │ ├── network.C │ ├── batchrecv.H │ ├── netserver.H │ ├── path.C │ ├── stat.C │ ├── batchsend.H │ ├── netserver.C │ ├── local.C │ ├── session.H │ ├── netconnection.H │ ├── config.H │ └── stat.H └── hi │ ├── funcdefs.H │ ├── www.H │ └── evaluator.H ├── renovate.json ├── NOTICE.md ├── .gitignore ├── docker └── build │ └── xenial.Dockerfile ├── include └── hobbes │ ├── boot │ └── gen │ │ └── boot.H │ ├── db │ ├── signals.H │ ├── bindings.H │ └── cbindings.H │ ├── ipc │ ├── nbindings.H │ ├── procman.H │ ├── prepl.H │ └── process.H │ ├── lang │ ├── preds │ │ ├── str.H │ │ ├── hasfield │ │ │ ├── record.H │ │ │ ├── tenvlookup.H │ │ │ ├── lookup.H │ │ │ └── slookup.H │ │ ├── hasctor │ │ │ └── variant.H │ │ ├── appendsto │ │ │ └── record.H │ │ ├── sizeof.H │ │ ├── cpptdesc.H │ │ ├── recty.H │ │ ├── equal.H │ │ ├── not.H │ │ ├── data.H │ │ ├── loadref.H │ │ ├── typeof.H │ │ ├── packsto.H │ │ ├── deconstruct.H │ │ ├── vtrunc.H │ │ ├── vapp.H │ │ ├── consvariant.H │ │ ├── consrecord.H │ │ ├── hasctor.H │ │ ├── subtype.H │ │ ├── appendsto.H │ │ ├── hasfield.H │ │ └── subtype │ │ │ └── obj.H │ ├── macroexpand.H │ ├── closcvt.H │ ├── pat │ │ ├── print.H │ │ └── regex.H │ ├── constraints.H │ └── typepreds.H │ ├── util │ ├── os.H │ ├── autorelease.H │ ├── region.H │ ├── hash.H │ ├── preprocessor.H │ ├── lannotation.H │ ├── func.H │ └── perf.H │ ├── eval │ ├── funcdefs.H │ ├── ctype.H │ ├── cexpr.H │ ├── search.H │ ├── func.H │ ├── orcjitcc.H │ └── cmodule.H │ ├── events │ ├── httpd.H │ └── events.H │ ├── read │ └── parser.H │ ├── parse │ ├── parser.H │ ├── data.H │ ├── terminal.H │ └── grammar.H │ └── hobbes.H ├── lib └── hobbes │ ├── boot │ ├── hasdef.hob │ ├── gen │ │ └── boot.C │ ├── strings.hob │ ├── bootgen.sh │ ├── fstrfns.hob │ ├── flip.hob │ ├── read.hob │ ├── storeslmap.hob │ ├── lookup.hob │ ├── set.hob │ └── streams.hob │ ├── read │ └── pgen │ │ └── pgen.sh │ ├── lang │ ├── tyunqualify.C │ ├── preds │ │ ├── equal.C │ │ ├── not.C │ │ ├── data.C │ │ ├── sizeof.C │ │ ├── hasctor │ │ │ └── variant.C │ │ ├── typeof.C │ │ ├── subtype.C │ │ ├── appendsto.C │ │ └── vtrunc.C │ └── constraints.C │ ├── parse │ ├── terminal.C │ ├── data.C │ └── grammar.C │ └── eval │ └── orcjitcc.C ├── doc └── en │ ├── networking │ ├── datatypes.rst │ └── cpp.rst │ ├── conf.py │ ├── about.rst │ ├── logging │ └── datatypes.rst │ ├── introduction │ └── components.rst │ ├── index.rst │ └── appendix │ └── hi.rst ├── test ├── Existentials.C ├── Recursives.C ├── TypeInf.C ├── mocks │ └── proc.C ├── Spawn.C ├── PREPL.C ├── Convert.C ├── format.H └── Definitions.C ├── cmake └── FindReadline.cmake ├── default.nix ├── nix └── ubsan_supp.patch ├── flake.lock ├── flake.nix ├── scripts └── hobbes.vim └── .gitlab-ci.yml /.devcontainer/nix.conf: -------------------------------------------------------------------------------- 1 | experimental-features = nix-command flakes -------------------------------------------------------------------------------- /bin/hog/boot/bootgen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cat *.hob > ./.bootdata 4 | xxd -i ./.bootdata > gen/bootdata.H 5 | rm ./.bootdata 6 | 7 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /NOTICE.md: -------------------------------------------------------------------------------- 1 | 2 | Copyright 2017 Morgan Stanley. 3 | 4 | This product includes software developed at Morgan Stanley (http://www.morganstanley.com). 5 | 6 | 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.sw? 2 | /build/ 3 | __pycache__/ 4 | *.py[cod] 5 | CMakeCache.txt 6 | CMakeFiles/ 7 | /doc/en/_build/ 8 | /doc/building.txt 9 | .vscode/ 10 | .gitmessage 11 | -------------------------------------------------------------------------------- /docker/build/xenial.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:noble 2 | ARG DEPS 3 | ENV ARGS -V 4 | RUN apt update 5 | RUN apt install -y ${DEPS} 6 | CMD mkdir -p /build && cd /build && cmake /src && VERBOSE=1 make -j2 && make test 7 | -------------------------------------------------------------------------------- /bin/hi/funcdefs.H: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HI_FUNCDEFS_HPP_INCLUDED 3 | #define HI_FUNCDEFS_HPP_INCLUDED 4 | 5 | #include 6 | 7 | namespace hi { 8 | 9 | void bindHiDefs(hobbes::cc&); 10 | 11 | } 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /bin/hog/boot/gen/boot.H: -------------------------------------------------------------------------------- 1 | #ifndef HOG_BOOT_COMPILE_HPP_INCLUDED 2 | #define HOG_BOOT_COMPILE_HPP_INCLUDED 3 | 4 | #include 5 | 6 | namespace hog { 7 | void compileBootCode(hobbes::cc&); 8 | } 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /bin/hog/path.H: -------------------------------------------------------------------------------- 1 | #ifndef HOG_PATH_H_INCLUDED 2 | #define HOG_PATH_H_INCLUDED 3 | 4 | #include 5 | 6 | namespace hog { 7 | 8 | std::string instantiateDir(const std::string& groupName, const std::string& dir); 9 | 10 | } 11 | 12 | #endif 13 | 14 | -------------------------------------------------------------------------------- /include/hobbes/boot/gen/boot.H: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HOBBES_BOOT_COMPILE_HPP_INCLUDED 3 | #define HOBBES_BOOT_COMPILE_HPP_INCLUDED 4 | 5 | #include 6 | 7 | namespace hobbes { 8 | 9 | void compileBootCode(cc& ctx); 10 | 11 | } 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /include/hobbes/db/signals.H: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HOBBES_DB_SIGNALS_HPP_INCLUDED 3 | #define HOBBES_DB_SIGNALS_HPP_INCLUDED 4 | 5 | #include 6 | 7 | namespace hobbes { 8 | 9 | void initSignalsDefs(FieldVerifier*,cc&); 10 | 11 | } 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /include/hobbes/ipc/nbindings.H: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HOBBES_LANG_TYPEPREDS_NET_CONNECTION_HPP_INCLUDED 3 | #define HOBBES_LANG_TYPEPREDS_NET_CONNECTION_HPP_INCLUDED 4 | 5 | namespace hobbes { 6 | 7 | class cc; 8 | void initNetworkDefs(cc&); 9 | 10 | } 11 | 12 | #endif 13 | 14 | -------------------------------------------------------------------------------- /bin/hog/out.H: -------------------------------------------------------------------------------- 1 | #include // showDateTime 2 | #include // time 3 | 4 | #include 5 | 6 | namespace hog { 7 | 8 | inline std::ostream& out() { 9 | return std::cout << "[" << hobbes::showDateTime(hobbes::time() / 1000) << "]: "; 10 | } 11 | 12 | } // namespace hog 13 | -------------------------------------------------------------------------------- /include/hobbes/lang/preds/str.H: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HOBBES_LANG_TYPEPREDS_STR_HPP_INCLUDED 3 | #define HOBBES_LANG_TYPEPREDS_STR_HPP_INCLUDED 4 | 5 | #include 6 | #include 7 | 8 | namespace hobbes { 9 | 10 | void initStrPredicates(const TEnvPtr&); 11 | 12 | } 13 | 14 | #endif 15 | 16 | -------------------------------------------------------------------------------- /lib/hobbes/boot/hasdef.hob: -------------------------------------------------------------------------------- 1 | /* 2 | * default 3 | */ 4 | 5 | class HasDef a where 6 | def :: a 7 | 8 | instance HasDef () where 9 | def = () 10 | 11 | instance (HasZero a) => HasDef a where 12 | def = zero 13 | 14 | instance HasDef [a] where 15 | def = [] 16 | 17 | instance (HasDef r) => HasDef (l+r) where 18 | def = |1=def| 19 | 20 | -------------------------------------------------------------------------------- /bin/hog/boot/gen/boot.C: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace hog { 6 | 7 | #include "bootdata.H" 8 | 9 | void compileBootCode(hobbes::cc& ctx) { 10 | hobbes::compile(&ctx, ctx.readModule(std::string(reinterpret_cast(_bootdata), _bootdata_len))); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /doc/en/networking/datatypes.rst: -------------------------------------------------------------------------------- 1 | .. _hobbes_network_serialisation_types: 2 | 3 | Data Types 4 | ********** 5 | 6 | The rules for which built-in types can be used in Hobbes networking are the same as for :ref:`Logging datatypes`. 7 | 8 | For custom datatypes, you should specialize ``hobbes::net::io``, or refer to ``hobbes/net.h`` in the GitHub repo. -------------------------------------------------------------------------------- /include/hobbes/db/bindings.H: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HOBBES_DB_BINDINGS_HPP_INCLUDED 3 | #define HOBBES_DB_BINDINGS_HPP_INCLUDED 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | namespace hobbes { 11 | 12 | void initStorageFileDefs(FieldVerifier*, cc&); 13 | 14 | } 15 | 16 | #endif 17 | 18 | -------------------------------------------------------------------------------- /bin/hog/recovery.H: -------------------------------------------------------------------------------- 1 | /* 2 | * recovery.H : provides utilities to recover information from the hogstat log, 3 | * detect potential faults, and to attempt to complete/recover operations 4 | */ 5 | 6 | #ifndef HOG_RECOVERY_H_INCLUDED 7 | #define HOG_RECOVERY_H_INCLUDED 8 | 9 | namespace hog { 10 | 11 | void detectFaultAndRecover(); 12 | 13 | } 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /include/hobbes/util/os.H: -------------------------------------------------------------------------------- 1 | /************ 2 | * os : utility definitions to decide what OS we are building on and how to do some common things 3 | ************/ 4 | 5 | #ifndef HOBBES_UTIL_OS_HPP_INCLUDED 6 | #define HOBBES_UTIL_OS_HPP_INCLUDED 7 | 8 | #if defined(__APPLE__) && defined(__MACH__) 9 | #include 10 | #define BUILD_OSX 11 | #else 12 | #define BUILD_LINUX 13 | #endif 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /lib/hobbes/boot/gen/boot.C: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace hobbes { 6 | 7 | #include 8 | 9 | void compileBootCode(cc& ctx) { 10 | for (size_t i = 0; module_defs[i] != nullptr; ++i) { 11 | compile(&ctx, ctx.readModule(std::string(reinterpret_cast(module_defs[i]), module_lens[i]))); 12 | } 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /lib/hobbes/read/pgen/pgen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd `dirname ${BASH_SOURCE[0]}` 4 | 5 | # generate the LALR(1) parser and token definitions 6 | ${BISON:-bison} -d -ohexpr.parse.C hexpr.y 7 | sed -i 's,#include "hexpr.parse.H",//&,' hexpr.parse.C 8 | 9 | # obey internal convention for division of source and header files 10 | mv hexpr.parse.H ../../../../include/hobbes/read/pgen/ 11 | 12 | # generate the lexer to tokenize string input 13 | ${LEX:-flex} -ohexpr.lex.C hexpr.l 14 | -------------------------------------------------------------------------------- /include/hobbes/eval/funcdefs.H: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HOBBES_EVAL_FUNCDEFS_HPP_INCLUDED 3 | #define HOBBES_EVAL_FUNCDEFS_HPP_INCLUDED 4 | 5 | #include 6 | 7 | namespace hobbes { 8 | 9 | void initStdFuncDefs(cc& ctx); 10 | 11 | // pooled memory allocation 12 | char* memalloc(size_t, size_t); 13 | 14 | // dynamic string construction utilities 15 | const array* makeString(const std::string& x); 16 | std::string makeStdString(const array* x); 17 | 18 | } 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /bin/hog/network.H: -------------------------------------------------------------------------------- 1 | #ifndef HOG_NETWORK_H_INCLUDED 2 | #define HOG_NETWORK_H_INCLUDED 3 | 4 | #include "netconnection.H" 5 | #include "netserver.H" 6 | 7 | #include 8 | 9 | namespace hog { 10 | 11 | std::unique_ptr createNetServer(const std::string& hostport); 12 | 13 | std::unique_ptr createNetConnection(const std::string& hostport); 14 | std::unique_ptr createNetConnection(int fd); 15 | 16 | } // namespace hog 17 | 18 | #endif // HOG_NETWORK_H_INCLUDED 19 | -------------------------------------------------------------------------------- /include/hobbes/eval/ctype.H: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HOBBES_EVAL_TYPE_HPP_INCLUDED 3 | #define HOBBES_EVAL_TYPE_HPP_INCLUDED 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace hobbes { 10 | 11 | llvm::Type* llvmVarArrType(llvm::Type* elemty, int size = 1); // 'size' is a hint for array size but not necessarily meaningful 12 | 13 | llvm::Type* toLLVM(const MonoTypePtr&, bool asArg = false); 14 | Types toLLVM(const MonoTypes&, bool asArg = false); 15 | 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /include/hobbes/lang/macroexpand.H: -------------------------------------------------------------------------------- 1 | #ifndef HOBBES_LANG_MACROEXPAND_HPP_INCLUDED 2 | #define HOBBES_LANG_MACROEXPAND_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | 7 | namespace hobbes { 8 | 9 | // give a type assignment to all macros (so that they can be safely type-checked, even if they're just expanded inline) 10 | void initMacroEnvironment(const TEnvPtr& tenv); 11 | 12 | // macro-expand an expression 13 | ExprPtr macroExpand(const ExprPtr& e); 14 | 15 | } 16 | 17 | #endif 18 | 19 | -------------------------------------------------------------------------------- /bin/hog/local.H: -------------------------------------------------------------------------------- 1 | /* 2 | * local : write structured data to local disk files 3 | */ 4 | 5 | #ifndef HOG_LOCAL_H_INCLUDED 6 | #define HOG_LOCAL_H_INCLUDED 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "session.H" 14 | 15 | namespace hog { 16 | void recordLocalData(SessionGroup*, const hobbes::storage::QueueConnection&, const std::string& dir, const hobbes::storage::WaitPolicy, std::atomic& conn); 17 | } 18 | 19 | #endif 20 | 21 | -------------------------------------------------------------------------------- /include/hobbes/lang/closcvt.H: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HOBBES_LANG_CLOSCVT_HPP_INCLUDED 3 | #define HOBBES_LANG_CLOSCVT_HPP_INCLUDED 4 | 5 | #include 6 | #include 7 | 8 | namespace hobbes { 9 | 10 | // translate uses of lexically-scoped nested functions to explicit closures 11 | ExprPtr closureConvert(const TEnvPtr& rootTEnv, const ExprPtr& e); 12 | 13 | // closure-convert recursive definitions 14 | ExprPtr closureConvert(const TEnvPtr& rootTEnv, const std::string& vn, const ExprPtr& e); 15 | 16 | } 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /.devcontainer/profile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PROJECT_DIR=${PROJECT_DIR:-/workspace} 4 | 5 | # Make Nix available as it's not installed system-wide. 6 | if [ -e $HOME/.nix-profile/etc/profile.d/nix.sh ] ; then 7 | . $HOME/.nix-profile/etc/profile.d/nix.sh 8 | fi 9 | 10 | # Only load the development environment if this is a login shell so calling a 11 | # shell later on doesn't reload the environment again. 12 | if shopt -q login_shell; then 13 | pushd "${PROJECT_DIR}" 14 | eval "$(nix print-dev-env --profile "${PROJECT_DIR}/.devcontainer/.profile")" 15 | popd 16 | fi -------------------------------------------------------------------------------- /doc/en/conf.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | sys.path.insert(0, os.path.join( 5 | os.path.dirname(os.path.abspath(__file__)), 6 | os.path.join('..', '..'))) 7 | 8 | extensions = [ 9 | 'sphinx.ext.autodoc', 10 | 'sphinx.ext.viewcode' 11 | ] 12 | 13 | project = 'Hobbes' 14 | copyright = '2018, Morgan Stanley' 15 | author = '' 16 | 17 | master_doc = 'index' 18 | 19 | pygments_style = 'sphinx' 20 | html_theme = 'sphinx_rtd_theme' 21 | 22 | html_static_path = ['_static'] 23 | 24 | def setup(app): 25 | app.add_stylesheet('icon.css') -------------------------------------------------------------------------------- /bin/hog/network.C: -------------------------------------------------------------------------------- 1 | #include "network.H" 2 | 3 | namespace hog { 4 | 5 | std::unique_ptr createNetServer(const std::string& hostport) 6 | { 7 | return std::unique_ptr(new DefaultNetServer(hostport)); 8 | } 9 | 10 | std::unique_ptr createNetConnection(const std::string& hostport) 11 | { 12 | return std::unique_ptr(new DefaultNetConnection(hostport)); 13 | } 14 | 15 | std::unique_ptr createNetConnection(int fd) 16 | { 17 | return std::unique_ptr(new DefaultNetConnection(fd)); 18 | } 19 | 20 | } // namespace hog 21 | -------------------------------------------------------------------------------- /include/hobbes/lang/pat/print.H: -------------------------------------------------------------------------------- 1 | /* 2 | * print : display intermediate structures for pattern matching translation 3 | */ 4 | 5 | #ifndef HOBBES_LANG_PAT_PRINT_HPP_INCLUDED 6 | #define HOBBES_LANG_PAT_PRINT_HPP_INCLUDED 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace hobbes { 13 | 14 | // pretty-print a final pattern match expression 15 | void printMatchResult(std::ostream&, const ExprPtr&); 16 | 17 | // pretty-print a pattern match table 18 | void printMatchTable(std::ostream&, const PatternRows&); 19 | 20 | } 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /lib/hobbes/boot/strings.hob: -------------------------------------------------------------------------------- 1 | /* 2 | * common string processing functions 3 | */ 4 | 5 | toLower :: char -> char 6 | toLower c = if (c >= 'A' and c <= 'Z') then ((c - 'A') + 'a') else c 7 | 8 | lcase :: (Array cs char) => cs -> [char] 9 | lcase cs = map(toLower, cs[0:]) 10 | 11 | toUpper :: char -> char 12 | toUpper c = if (c >= 'a' and c <= 'z') then ((c - 'a') + 'A') else c 13 | 14 | ucase :: (Array cs char) => cs -> [char] 15 | ucase cs = map(toUpper, cs[0:]) 16 | 17 | // approximate equality between strings is case-insensitive matching 18 | instance (Array as char, Array bs char) => ApproxEquiv as bs where 19 | as ~ bs = lcase(as) === lcase(bs) 20 | 21 | -------------------------------------------------------------------------------- /bin/hog/batchrecv.H: -------------------------------------------------------------------------------- 1 | /* 2 | * batchrecv : write local structured log files from compressed transaction data sent over a network 3 | */ 4 | 5 | #ifndef HOG_BATCHRECV_H_INCLUDED 6 | #define HOG_BATCHRECV_H_INCLUDED 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace hog { 14 | 15 | std::thread pullRemoteDataT(const std::string& dir, const std::string& listenport, bool consolidate, hobbes::StoredSeries::StorageMode sm); 16 | bool pullRemoteData(const std::string& dir, const std::string& listenport, bool consolidate, hobbes::StoredSeries::StorageMode sm); 17 | 18 | } 19 | 20 | #endif 21 | 22 | -------------------------------------------------------------------------------- /bin/hog/netserver.H: -------------------------------------------------------------------------------- 1 | #ifndef HOG_NETSERVER_H_INCLUDED 2 | #define HOG_NETSERVER_H_INCLUDED 3 | 4 | #include "netconnection.H" 5 | 6 | #include 7 | 8 | namespace hog { 9 | 10 | class NetServer { 11 | public: 12 | virtual ~NetServer() = default; 13 | 14 | virtual std::unique_ptr accept() = 0; 15 | }; 16 | 17 | class DefaultNetServer : public NetServer { 18 | public: 19 | explicit DefaultNetServer(const std::string& hostport); 20 | ~DefaultNetServer(); 21 | 22 | std::unique_ptr accept() override; 23 | 24 | private: 25 | int _socket; 26 | }; 27 | 28 | } // namespace hog 29 | 30 | #endif // HOG_NETSERVER_H_INCLUDED 31 | -------------------------------------------------------------------------------- /lib/hobbes/boot/bootgen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd `dirname ${BASH_SOURCE[0]}` 4 | 5 | GENFILE=../../../include/hobbes/boot/gen/bootdata.H 6 | 7 | rm -f $GENFILE 8 | 9 | for script in `ls ./*.hob` 10 | do 11 | xxd -i $script | sed 's/ __/ _/' >> $GENFILE 12 | done 13 | 14 | echo "unsigned char* module_defs[] = {" >> $GENFILE 15 | for script in `ls *.hob` 16 | do 17 | echo _"$script," | sed 's/\./_/g' >> $GENFILE 18 | done 19 | echo "nullptr };" >> $GENFILE 20 | 21 | echo "unsigned int module_lens[] = {" >> $GENFILE 22 | for script in `ls *.hob` 23 | do 24 | echo _"$script""_len," | sed 's/\./_/g' >> $GENFILE 25 | done 26 | echo "0u };" >> $GENFILE 27 | 28 | -------------------------------------------------------------------------------- /lib/hobbes/boot/fstrfns.hob: -------------------------------------------------------------------------------- 1 | 2 | findSubseqStep :: (Equiv a b) => ([a], [b], long, long) -> long 3 | findSubseqStep s ss i j = 4 | if (i == length(s) or j == length(ss)) then 5 | (i-j) 6 | else if (s[i] == ss[j]) then 7 | findSubseqStep(s, ss, i+1, j+1) 8 | else 9 | findSubseqStep(s, ss, (i-j)+1, 0L) 10 | {-# UNSAFE findSubseqStep #-} 11 | 12 | findSubseq :: (Equiv a b) => ([a], [b]) -> long 13 | findSubseq s ss = findSubseqStep(s, ss, 0L, 0L) 14 | {-# SAFE findSubseq #-} 15 | 16 | lsplit :: (Equiv a b) => ([a], [b]) -> ([a]*[a]) 17 | lsplit s ss = 18 | let 19 | n = findSubseq(s, ss) 20 | in 21 | (selectRange(s, 0L, n), selectRange(s, n + length(ss), length(s))) 22 | 23 | -------------------------------------------------------------------------------- /test/Existentials.C: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "test.H" 4 | 5 | using namespace hobbes; 6 | static cc& c() { static cc x; return x; } 7 | 8 | TEST(Existentials, Basic) { 9 | c().define("exf", "\\x.((pack ((\\e y.iadd(e.x,y))::({x:int},int)->int,{x=x}))::exists E.(((E,int)->int)*E))"); 10 | 11 | // test explicit existential package construction/deconstruction 12 | EXPECT_EQ(c().compileFn("unpack z = (exf(10)) in (z.0(z.1,5))")(), 15); 13 | } 14 | 15 | TEST(Existentials, Closures) { 16 | // does closure-conversion implicitly produce an existential package as required? 17 | EXPECT_EQ(c().compileFn("unpack z = ((\\x.\\y.x+y)(10)) in (z.0(z.1,5))")(), 15); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /bin/hog/path.C: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "path.H" 4 | 5 | namespace hog { 6 | 7 | std::string instantiateDir(const std::string& groupName, const std::string& dir) { 8 | // instantiate group name 9 | std::string x = hobbes::str::replace(dir, "$GROUP", groupName); 10 | 11 | // instantiate date 12 | time_t now = ::time(nullptr); 13 | if (const tm* t = localtime(&now)) { 14 | std::ostringstream ss; 15 | ss << t->tm_year + 1900 << "." << (t->tm_mon < 9 ? "0" : "") << t->tm_mon + 1 << "." << (t->tm_mday < 10 ? "0" : "") << t->tm_mday; 16 | x = hobbes::str::replace(x, "$DATE", ss.str()); 17 | } 18 | 19 | // that's all we will substitute 20 | return x; 21 | } 22 | 23 | } 24 | 25 | -------------------------------------------------------------------------------- /bin/hog/stat.C: -------------------------------------------------------------------------------- 1 | #include "stat.H" 2 | 3 | #include 4 | 5 | #include 6 | 7 | namespace hog { 8 | 9 | std::string StatFile::directory = hobbes::storage::defaultStoreDir(); 10 | 11 | StatFile& StatFile::instance() { 12 | static StatFile statFile; 13 | return statFile; 14 | } 15 | 16 | StatFile::StatFile() : statFile(StatFile::directory + "/hogstat.db") {} 17 | 18 | size_t createSessionHash(const hobbes::datetimeT& timestamp, const hobbes::storage::ProcThread& pt) { 19 | const hobbes::genHash hasher; 20 | size_t hashed = hasher(timestamp.value); 21 | hobbes::hashAppend(hashed, pt.first); 22 | hobbes::hashAppend(hashed, pt.second); 23 | return hashed; 24 | } 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /bin/hog/batchsend.H: -------------------------------------------------------------------------------- 1 | /* 2 | * batchsend : write structured data to a remote process in (compressed) batches 3 | */ 4 | 5 | #ifndef HOG_BATCHSEND_H_INCLUDED 6 | #define HOG_BATCHSEND_H_INCLUDED 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "config.H" 14 | 15 | namespace hog { 16 | 17 | void pushLocalData(const hobbes::storage::QueueConnection& qc, const size_t sessionHash, const std::string& groupName, const std::string& partialDir, const std::string& fullDir, const hobbes::storage::ProcThread& readerId, const hobbes::storage::WaitPolicy wp, const RunMode& runMode, std::atomic& conn, const std::function& finalizeSenderF = []() {}); 18 | 19 | } 20 | 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /test/Recursives.C: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "test.H" 4 | 5 | using namespace hobbes; 6 | static cc& c() { static cc x; return x; } 7 | 8 | TEST(Recursives, Lists) { 9 | // make a dummy linked list from C++ to verify that binding between hobbes and C++ is correct 10 | static seq nil; 11 | static seq tn(3, &nil); 12 | static seq ttn(2, &tn); 13 | static seq ottn(1, &ttn); 14 | 15 | c().bind("rectyll", &ottn); 16 | 17 | EXPECT_TRUE(c().compileFn("show(rectyll) == \"1:2:3:[]\"")()); 18 | EXPECT_TRUE(c().compileFn("show(cons(1,cons(2,cons(3,nil())))) == \"1:2:3:[]\"")()); 19 | EXPECT_TRUE(c().compileFn("show(lmap(\\x.x+1, cons(1,cons(2,cons(3,nil()))))) == \"2:3:4:[]\"")()); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /include/hobbes/eval/cexpr.H: -------------------------------------------------------------------------------- 1 | #ifndef HOBBES_EVAL_CEXPR_HPP_INCLUDED 2 | #define HOBBES_EVAL_CEXPR_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace hobbes { 9 | 10 | llvm::Value* toLLVM(jitcc*, const ExprPtr& exp); 11 | 12 | // used for compiling recursive functions 13 | llvm::Value* toLLVM(jitcc* e, const std::string& vname, const ExprPtr& exp); 14 | 15 | // used for compiling primitive integral values 16 | llvm::ConstantInt* toLLVMConstantInt(const PrimitivePtr&); 17 | 18 | // used for compiling any constant value (if it can't be compiled as a constant, null will be returned) 19 | llvm::Constant* toLLVMConstant(jitcc*, const std::string&, const ExprPtr&); 20 | 21 | } 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/hobbes/lang/preds/hasfield/record.H: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HOBBES_LANG_TYPEPREDS_HASFIELD_RECORD_HPP_INCLUDED 3 | #define HOBBES_LANG_TYPEPREDS_HASFIELD_RECORD_HPP_INCLUDED 4 | 5 | #include 6 | 7 | namespace hobbes { 8 | 9 | struct HFRecordEliminator : public HFEliminator { 10 | bool satisfied(const TEnvPtr& tenv, const HasField&, Definitions*) const override; 11 | bool satisfiable(const TEnvPtr& tenv, const HasField&, Definitions*) const override; 12 | bool refine(const TEnvPtr& tenv, const HasField&, MonoTypeUnifier* s, Definitions*) override; 13 | ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*) const override; 14 | std::string name() const override; 15 | }; 16 | 17 | } 18 | 19 | #endif 20 | 21 | -------------------------------------------------------------------------------- /include/hobbes/lang/preds/hasfield/tenvlookup.H: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HOBBES_LANG_TYPEPREDS_HASFIELD_TENVLOOKUP_HPP_INCLUDED 3 | #define HOBBES_LANG_TYPEPREDS_HASFIELD_TENVLOOKUP_HPP_INCLUDED 4 | 5 | #include 6 | 7 | namespace hobbes { 8 | 9 | struct HFTEnvLookupEliminator : public HFEliminator { 10 | bool satisfied(const TEnvPtr& tenv, const HasField&, Definitions*) const override; 11 | bool satisfiable(const TEnvPtr& tenv, const HasField&, Definitions*) const override; 12 | bool refine(const TEnvPtr& tenv, const HasField&, MonoTypeUnifier* s, Definitions*) override; 13 | ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*) const override; 14 | std::string name() const override; 15 | }; 16 | 17 | } 18 | 19 | #endif 20 | 21 | -------------------------------------------------------------------------------- /bin/hog/netserver.C: -------------------------------------------------------------------------------- 1 | #include "netserver.H" 2 | #include "network.H" 3 | 4 | #include 5 | 6 | #include 7 | #include // close 8 | 9 | namespace hog { 10 | 11 | // TODO allocateServer does not support host, only port 12 | // - that's an issue if the host has multiple net device 13 | DefaultNetServer::DefaultNetServer(const std::string& hostport) 14 | :_socket(hobbes::allocateServer(hostport)) // throws on error 15 | {} 16 | 17 | DefaultNetServer::~DefaultNetServer() 18 | { 19 | close(_socket); 20 | } 21 | 22 | std::unique_ptr DefaultNetServer::accept() { 23 | const int client = ::accept(_socket, nullptr, nullptr); 24 | if (client < 0) { 25 | return {}; 26 | } 27 | 28 | return createNetConnection(client); 29 | } 30 | 31 | } // namespace hog 32 | -------------------------------------------------------------------------------- /include/hobbes/events/httpd.H: -------------------------------------------------------------------------------- 1 | /***************************************** 2 | * an optional quick-and-dirty web server that works through events 3 | ****************************************/ 4 | 5 | #ifndef HOBBES_EVENTS_HTTPD_HPP_INCLUDED 6 | #define HOBBES_EVENTS_HTTPD_HPP_INCLUDED 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace hobbes { 13 | 14 | struct HTTPRequest { 15 | using Headers = std::map; 16 | using Data = std::vector; 17 | 18 | std::string method; 19 | std::string document; 20 | Headers headers; 21 | Data data; 22 | }; 23 | 24 | using HTTPRequestHandler = void (*)(const HTTPRequest &, int, void *); 25 | 26 | int installHTTPD(int port, HTTPRequestHandler, void* ud = nullptr); 27 | 28 | } 29 | 30 | #endif 31 | 32 | -------------------------------------------------------------------------------- /include/hobbes/lang/preds/hasctor/variant.H: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HOBBES_LANG_TYPEPREDS_HASCTOR_VARIANT_HPP_INCLUDED 3 | #define HOBBES_LANG_TYPEPREDS_HASCTOR_VARIANT_HPP_INCLUDED 4 | 5 | #include 6 | 7 | namespace hobbes { 8 | 9 | struct HCVariantEliminator : public HCEliminator { 10 | bool satisfied(const TEnvPtr& tenv, const HasCtor&, Definitions*) const override; 11 | bool satisfiable(const TEnvPtr& tenv, const HasCtor&, Definitions*) const override; 12 | bool refine(const TEnvPtr& tenv, const HasCtor&, MonoTypeUnifier* s, Definitions*) override; 13 | ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const HasCtor&, const ExprPtr&, Definitions*) const override; 14 | std::string name() const override; 15 | }; 16 | 17 | const Variant* isVariantPEnum(const MonoTypePtr& e); 18 | 19 | } 20 | 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /include/hobbes/lang/preds/hasfield/lookup.H: -------------------------------------------------------------------------------- 1 | // eliminate (A.x :: T) constraints by trying to compile lookup(value(x), A) :: T 2 | 3 | #ifndef HOBBES_LANG_TYPEPREDS_HASFIELD_LOOKUP_HPP_INCLUDED 4 | #define HOBBES_LANG_TYPEPREDS_HASFIELD_LOOKUP_HPP_INCLUDED 5 | 6 | #include 7 | 8 | namespace hobbes { 9 | 10 | struct HFLookupEliminator : public HFEliminator { 11 | bool satisfied(const TEnvPtr& tenv, const HasField&, Definitions*) const override; 12 | bool satisfiable(const TEnvPtr& tenv, const HasField&, Definitions*) const override; 13 | bool refine(const TEnvPtr& tenv, const HasField&, MonoTypeUnifier* s, Definitions*) override; 14 | ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*) const override; 15 | std::string name() const override; 16 | }; 17 | 18 | } 19 | 20 | #endif 21 | 22 | -------------------------------------------------------------------------------- /include/hobbes/lang/preds/hasfield/slookup.H: -------------------------------------------------------------------------------- 1 | // eliminate (A.x :: T) constraints by trying to compile slookup(A) :: (SLookup typeof(A) value(x) T) => T 2 | 3 | #ifndef HOBBES_LANG_TYPEPREDS_HASFIELD_SLOOKUP_HPP_INCLUDED 4 | #define HOBBES_LANG_TYPEPREDS_HASFIELD_SLOOKUP_HPP_INCLUDED 5 | 6 | #include 7 | 8 | namespace hobbes { 9 | 10 | struct HFSLookupEliminator : public HFEliminator { 11 | bool satisfied(const TEnvPtr& tenv, const HasField&, Definitions*) const override; 12 | bool satisfiable(const TEnvPtr& tenv, const HasField&, Definitions*) const override; 13 | bool refine(const TEnvPtr& tenv, const HasField&, MonoTypeUnifier* s, Definitions*) override; 14 | ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*) const override; 15 | std::string name() const override; 16 | }; 17 | 18 | } 19 | 20 | #endif 21 | 22 | -------------------------------------------------------------------------------- /lib/hobbes/boot/flip.hob: -------------------------------------------------------------------------------- 1 | 2 | // flip an array of records into a record of arrays 3 | 4 | class FlipType a b | a -> b 5 | instance FlipType () () 6 | instance (a={lbl:h*it}, FlipType it ot, {lbl:[h]*ot}=b) => FlipType a b 7 | 8 | class FlipInto a b where 9 | flipInto :: ([a],b) -> () 10 | 11 | // [doc] converts from an array of records into a record of arrays 12 | // [eg] [{a:int, b:bool}] -> {a:[int], b:[bool]} 13 | flip :: (FlipType a b) => [a] -> b 14 | flip xs = let r = newPrim(); _ = flipInto(xs, r) in r 15 | {-# SAFE flip #-} 16 | 17 | instance (a={lbl:h*()}, b={lbl:[h]*()}) => FlipInto a b where 18 | flipInto xs y = recordHeadValue(y) <- map(recordHeadValue, xs) 19 | 20 | instance (a={lbl:h*at}, b={lbl:[h]*bt}, FlipInto at bt) => FlipInto a b where 21 | flipInto xs y = let _ = (recordHeadValue(y) <- map(recordHeadValue, xs)) in flipInto(unsafeCast(xs) :: [at], recordTail(y)) 22 | 23 | -------------------------------------------------------------------------------- /cmake/FindReadline.cmake: -------------------------------------------------------------------------------- 1 | find_path(Readline_ROOT_DIR 2 | NAMES include/readline/readline.h 3 | HINTS /usr/local/opt/readline/ 4 | NO_DEFAULT_PATH 5 | ) 6 | 7 | find_path(Readline_INCLUDE_DIRS 8 | NAMES readline/readline.h 9 | HINTS ${Readline_ROOT_DIR}/include 10 | ) 11 | 12 | find_library(Readline_LIBRARIES 13 | NAMES readline 14 | HINTS ${Readline_ROOT_DIR}/lib 15 | ) 16 | 17 | if(Readline_INCLUDE_DIRS AND Readline_LIBRARIES AND Ncurses_LIBRARY) 18 | set(READLINE_FOUND TRUE) 19 | else() 20 | find_library(Readline_LIBRARIES NAMES readline) 21 | include(FindPackageHandleStandardArgs) 22 | find_package_handle_standard_args(Readline DEFAULT_MSG Readline_INCLUDE_DIRS Readline_LIBRARIES) 23 | mark_as_advanced(Readline_INCLUDE_DIRS Readline_LIBRARIES) 24 | endif() 25 | 26 | mark_as_advanced( 27 | Readline_ROOT_DIR 28 | Readline_INCLUDE_DIRS 29 | Readline_LIBRARIES 30 | ) 31 | 32 | -------------------------------------------------------------------------------- /include/hobbes/db/cbindings.H: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HOBBES_DB_CBINDINGS_HPP_INCLUDED 3 | #define HOBBES_DB_CBINDINGS_HPP_INCLUDED 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace hobbes { 13 | 14 | struct DynDModel0; 15 | 16 | class UCWriter { 17 | public: 18 | UCWriter(writer*, size_t root, size_t batchSize, size_t modelSize); 19 | void write(DynDModel0* dm, uint8_t c); 20 | bool step(); 21 | size_t currentInitModel() const; 22 | uint8_t* currentInitModelData() const; 23 | private: 24 | size_t batchSize; 25 | size_t modelSize; 26 | 27 | uint64_t scratchModelRef; 28 | uint8_t* scratchModel; 29 | 30 | fregion::cwbitstream out; 31 | }; 32 | 33 | 34 | void initCStorageFileDefs(FieldVerifier*, cc&); 35 | 36 | } 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/devcontainers/base:dev-ubuntu-22.04 2 | 3 | # These dependencies are required by Nix. 4 | RUN apt update -y 5 | RUN apt -y install --no-install-recommends curl xz-utils cmake libreadline-dev libncurses-dev llvm-12 llvm-12-dev 6 | RUN [ -e /usr/bin/gmake ] || sudo ln -s /usr/bin/make /usr/bin/gmake 7 | 8 | # Install Nix 9 | ARG NIX_INSTALL_SCRIPT=https://nixos.org/nix/install 10 | RUN curl -L ${NIX_INSTALL_SCRIPT} | sudo -u vscode NIX_INSTALLER_NO_MODIFY_PROFILE=1 sh 11 | 12 | # Configuration for Nix from the repository shared amongst developers. 13 | RUN mkdir -p /etc/nix 14 | COPY .devcontainer/nix.conf /etc/nix/nix.conf 15 | # COPY nix.conf /etc/nix/nix.conf 16 | 17 | # This loads the development environment when the container is started. 18 | COPY .devcontainer/profile.sh /etc/profile.d/devcontainer.sh 19 | 20 | # COPY /home/vscode/.nix-profile/etc/profile.d/nix.sh /etc/profile.d/devcontainer.sh -------------------------------------------------------------------------------- /include/hobbes/lang/preds/appendsto/record.H: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HOBBES_LANG_TYPEPREDS_APPENDSTO_RECORD_HPP_INCLUDED 3 | #define HOBBES_LANG_TYPEPREDS_APPENDSTO_RECORD_HPP_INCLUDED 4 | 5 | #include 6 | 7 | namespace hobbes { 8 | 9 | struct ATRecordEliminator : public ATEliminator { 10 | bool satisfied(const TEnvPtr& tenv, const MonoTypePtr& rty, const MonoTypePtr& fname, const MonoTypePtr& fty) const override; 11 | bool satisfiable(const TEnvPtr& tenv, const MonoTypePtr& rty, const MonoTypePtr& fname, const MonoTypePtr& fty) const override; 12 | bool refine(const TEnvPtr& tenv, const MonoTypePtr& rty, const MonoTypePtr& fieldName, const MonoTypePtr& fty, MonoTypeUnifier* s) override; 13 | PolyTypePtr lookup(const std::string& vn) const override; 14 | SymSet bindings() const override; 15 | ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*) const override; 16 | }; 17 | 18 | } 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | { nixpkgs ? import (fetchTarball { url="https://github.com/NixOs/nixpkgs/archive/a3ab47ec9067b5f9fccda506fc8641484c3d8e73.tar.gz"; 2 | sha256="1f1q89ka73ksvl5hgbrf624x0niwm2rg3dzxiscir0bji6zvjy15"; 3 | }), 4 | }: 5 | let 6 | overlays = [ 7 | (import ./nix/overlays.nix { 8 | version = "unstable"; 9 | system = builtins.currentSystem; 10 | src = ./.; 11 | llvmVersions = [ 6 8 9 10 11 ]; 12 | gccConstraints = [ 13 | { gccVersion = 6; llvmVersions = [ 6 8 9 ]; } 14 | { gccVersion = 8; llvmVersions = [ 6 8 9 10 11 ]; } 15 | { gccVersion = 9; llvmVersions = [ 6 8 9 10 11 ]; } 16 | { gccVersion = 10; llvmVersions = [ 6 8 9 10 11 ]; } 17 | ]; 18 | }) 19 | ]; 20 | 21 | pkgs = nixpkgs { 22 | inherit overlays; 23 | }; 24 | in with pkgs; recurseIntoAttrs { 25 | inherit hobbesPackages; 26 | inherit (hobbesPackages.gcc-8.llvm-6) hobbes; 27 | } 28 | -------------------------------------------------------------------------------- /include/hobbes/eval/search.H: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HOBBES_EVAL_SEARCH_HPP_INCLUDED 3 | #define HOBBES_EVAL_SEARCH_HPP_INCLUDED 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace hobbes { 12 | 13 | struct SearchEntry { 14 | LexicalAnnotation la; // where in a user's source this entry comes from 15 | std::string sym; // a symbol matching a user query 16 | MonoTypePtr ty; // the exact result type given by this symbol 17 | }; 18 | using SearchEntries = std::vector; 19 | 20 | struct SearchCache { 21 | std::map univByType; 22 | }; 23 | class cc; 24 | 25 | // find functions/properties from an expression/type to reach a result type 26 | SearchEntries search(cc&, SearchCache&, const MonoTypePtr&, const MonoTypePtr&); 27 | SearchEntries search(cc&, SearchCache&, const ExprPtr&, const MonoTypePtr&); 28 | 29 | } 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /nix/ubsan_supp.patch: -------------------------------------------------------------------------------- 1 | diff --git a/include/hobbes/reflect.H b/include/hobbes/reflect.H 2 | index b575156..1b1132d 100644 3 | --- a/include/hobbes/reflect.H 4 | +++ b/include/hobbes/reflect.H 5 | @@ -526,6 +526,9 @@ template