Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 30 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,38 @@
# Slothscript

A slow scripting language.
A scripting language for automation and system administration.

```sloth
func fib(n) {
if n <= 1 { return n }
fib(n - 1) + fib(n - 2)
# Single quotes delimit raw string literals, not supporting escapes or
# interpolation
let cxx = 'clang++'
let build_mode = 'Debug'
let generator = 'Ninja'

# $scriptDir is set by the runtime to be the directory containing the
# currently running script (not necessarily the working directory).
#
# Double quotes delimit rich string literals, `${ expression }` is used for string
# interpolation
let build = Directory("${$scriptDir}/build")

if not build.exists() {
build.create()
}

print(fib(20))
# Within this block, set the current working directory to be our build
# directory
with ($cwd = build.path) {
# The `!` postfix operator means spawn a sub-process, using the expression
# preceding it as a command and argument list, then block until the process
# exits
[
'cmake', $scriptDir,
"-DCMAKE_CXX_COMPILER=${cxx}",
"-DCMAKE_BUILD_TYPE=${build_mode}",
'-G', generator,
]!
}
```

## Installation
Expand Down Expand Up @@ -70,6 +94,7 @@ print(counter())
- `false` - `Bool` literal
- `null` - `Null` literal singleton
- `not` - prefix logical NOT operator; `assert(not false)`
- `throw` - raise an exception

### Context Variables

Expand Down
5 changes: 3 additions & 2 deletions README.tmpl.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Slothscript

A slow scripting language.
A scripting language for automation and system administration.

```sloth
{{ .test_green_specs_fibonacci_sloth }}
{{ .test_green_specs_configure_cmake_sloth }}
```

## Installation
Expand Down Expand Up @@ -53,6 +53,7 @@ First-class functions:
- `false` - `Bool` literal
- `null` - `Null` literal singleton
- `not` - prefix logical NOT operator; `assert(not false)`
- `throw` - raise an exception

### Context Variables

Expand Down
4 changes: 2 additions & 2 deletions dbc.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
"output": "README.md",
"template": "README.tmpl.md",
"inputs": [
"test/green_specs/fibonacci.sloth",
"test/green_specs/configure_cmake.sloth",
"test/green_specs/var_reference.sloth",
"test/green_specs/first_class_func.sloth",
"docs/context.md"
]
},
{
"output": "test/green_specs/fibonacci.sloth",
"output": "test/green_specs/configure_cmake.sloth",
"filter": "awk '/### Program/{f=1; next} /### /{f=0} f'"
},
{
Expand Down
4 changes: 2 additions & 2 deletions dune-project
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
(source
(github christopherfujino/slothscript))

(authors "Christopher Fujino")
(authors "Christopher Fujino <christopherfujino@gmail.com>")

(maintainers "Christopher Fujino")
(maintainers "Christopher Fujino <christopherfujino@gmail.com>")

(license "BSD-3-Clause")

Expand Down
2 changes: 1 addition & 1 deletion lib/interpreter/native.ml
Original file line number Diff line number Diff line change
Expand Up @@ -620,8 +620,8 @@ module Make_test () : TestSig = struct
| _ ->
let msg =
Printf.sprintf "Tried to execute sub-process %s but expected %s"
(List.to_string ~f:Fun.id hd.cmd)
(List.to_string ~f:Fun.id proc.cmd)
(List.to_string ~f:Fun.id hd.cmd)
in
Error msg)
in
Expand Down
4 changes: 4 additions & 0 deletions native/cpp/bytecode/.clangd
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CompileFlags:
# Un-comment this when we start building from Dune
#CompilationDatabase: ../..
CompilationDatabase: build/
38 changes: 38 additions & 0 deletions native/cpp/bytecode/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
## Global

cmake_minimum_required(VERSION 3.31)
project(slothscript-cpp-bytecode VERSION 0.1)

# These CMAKE_* variables apply to all future targets
set(CMAKE_CXX_EXTENSIONS OFF) # why don't want GNU extension
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Generate a compile_commands.json file
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# IWYU
find_program(IWYU_PATH NAMES include-what-you-use iwyu)
if(NOT IWYU_PATH)
message(FATAL_ERROR
"Could not find the program include-what-you-use (apt install iwyu)")
endif()
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${IWYU_PATH})

add_compile_options(-Wall -Werror -Wpedantic -Wextra)

# https://stackoverflow.com/questions/24648357/compiling-a-static-executable-with-cmake
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS "-static")

## Test exe

add_executable(test test.cpp)

target_link_libraries(test bytecode)
target_include_directories(test PRIVATE ../../../ignore/test.hpp)

## Bytecode library

add_library(bytecode STATIC bytecode.cpp)
37 changes: 37 additions & 0 deletions native/cpp/bytecode/bytecode.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "bytecode.hpp"

#include <format>
#include <stdexcept>
#include <utility>

std::string Chunk::debug() {
std::string message;
size_t byteSize = bytes.size();
for (size_t offset = 0; offset < byteSize;) {
auto pair = _debugInstruction(offset);
message += pair.first;
offset = pair.second;
}

return message;
}

std::pair<std::string, size_t> Chunk::_debugInstruction(size_t offset) {
std::string message = std::format("{: 4} ", offset);

switch ((OpCode)bytes[offset]) {
case OpCode::RETURN:
message += "RETURN\n";
return {message, offset + 1};
}
throw std::runtime_error("Unreachable");
}

Chunk::Chunk(std::vector<uint8_t> bytes) : bytes(bytes) {}

VM::VM(std::vector<Chunk> chunks) : _chunks(chunks) {
for (Chunk &chunk : chunks) {
// TODO: implement
ignore(chunk);
}
}
40 changes: 40 additions & 0 deletions native/cpp/bytecode/bytecode.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once

#include <cstdint>
#include <limits>
#include <stddef.h> // for size_t
#include <string>
#include <utility> // for pair
#include <vector>

static_assert(sizeof(double) == 8, "double is not 64-bit");
static_assert(std::numeric_limits<double>::is_iec559,
"double is not IEEE 754 compliant");

typedef double Value;

enum class OpCode : uint8_t {
RETURN,
};

class Chunk {
public:
Chunk(std::vector<uint8_t> bytes);

std::string debug();

std::vector<uint8_t> bytes;

private:
std::pair<std::string, size_t> _debugInstruction(size_t offset);
};

template <typename T> inline void ignore(T) {}

class VM {
public:
VM(std::vector<Chunk> chunks);

private:
std::vector<Chunk> _chunks;
};
31 changes: 31 additions & 0 deletions native/cpp/bytecode/configure.sloth
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env sloth

func ensureTestHpp() {
let testHppDir = Directory("${$scriptDir}/../../../ignore/test.hpp")
if not testHppDir.exists() {
let monorepoDir = Directory("${$scriptDir}/../../../../../cpp/test.hpp")
if monorepoDir.exists() {
# TODO make these realpaths
['ln', '-s', monorepoDir.path, testHppDir.path]!
} else {
let remote = 'git@github.com:christopherfujino/test.hpp.git'
['git', 'clone', '--depth=1', remote, testHppDir.path]!
}
}
}

ensureTestHpp()

let build = Directory("${$scriptDir}/build")
if not build.exists() {
build.create()
}

with ($cwd = build.path) {
[
'cmake', '..',
'-GNinja',
'-DCMAKE_CXX_COMPILER=clang++',
]!
'cmake --build .'!
}
19 changes: 19 additions & 0 deletions native/cpp/bytecode/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "test.hpp"
#include "bytecode.hpp"
#include <stdint.h>

using namespace _CHRIS_MONOREPO_CPP_TEST;

static std::vector<Test> tests = {
{"RETURN is 0", []() { expect((int)OpCode::RETURN, 0); }},
{"Chunk is just a vector",
[]() { expect((int)sizeof(Chunk), (int)sizeof(std::vector<void *>)); }},
{"Create a RETURN chunk",
[]() {
Chunk chunk{{(uint8_t)OpCode::RETURN}};
expect((int)chunk.bytes.size(), 1);
expect(chunk.debug(), std::string(" 0 RETURN\n"));
}},
};

int main() { return Runner(tests).run(); }
10 changes: 10 additions & 0 deletions native/cpp/bytecode/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash

set -euo pipefail

SCRIPTDIR="$( dirname "$( realpath "${BASH_SOURCE[0]}" )" )"

BUILD="${SCRIPTDIR}/build"

cmake --build "$BUILD"
"${BUILD}/test"
2 changes: 1 addition & 1 deletion native/dune
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
(data_only_dirs cpp)

(rule
(targets libsloth_native.a compile_commands.json)
(mode promote)
(deps
(source_tree cpp))
(targets libsloth_native.a compile_commands.json)
(action
; https://dune.readthedocs.io/en/stable/reference/actions/no-infer.html
; no infer because dune doesn't know how the targets are being created
Expand Down
4 changes: 2 additions & 2 deletions sloth_script.opam
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
opam-version: "2.0"
synopsis: "A slow scripting language"
description: "A longer description"
maintainer: ["Christopher Fujino"]
authors: ["Christopher Fujino"]
maintainer: ["Christopher Fujino <christopherfujino@gmail.com>"]
authors: ["Christopher Fujino <christopherfujino@gmail.com>"]
license: "BSD-3-Clause"
tags: ["topics" "to describe" "your" "project"]
homepage: "https://github.com/christopherfujino/slothscript"
Expand Down
Loading