mirror of
https://github.com/janet-lang/janet
synced 2024-12-01 04:19:55 +00:00
Switch over to Cmake fully.
This commit is contained in:
parent
b305a7c9bb
commit
ce5708af98
@ -1,6 +1,11 @@
|
|||||||
language: c
|
language: c
|
||||||
|
|
||||||
script: make test
|
script:
|
||||||
|
- mkdir -p build
|
||||||
|
- cd build
|
||||||
|
- cmake ..
|
||||||
|
- make
|
||||||
|
- make test
|
||||||
|
|
||||||
compiler:
|
compiler:
|
||||||
- clang
|
- clang
|
||||||
|
@ -18,18 +18,13 @@
|
|||||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
# IN THE SOFTWARE.
|
# IN THE SOFTWARE.
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.9)
|
cmake_minimum_required(VERSION 3.7)
|
||||||
project(dst)
|
project(dst)
|
||||||
|
|
||||||
# Set Some Variables
|
# Set Some Variables
|
||||||
set(TARGET_NAME ${PROJECT_NAME})
|
set(TARGET_NAME ${PROJECT_NAME})
|
||||||
if (CMAKE_VERSION VERSION_LESS "3.1")
|
set (CMAKE_C_STANDARD 99)
|
||||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
|
||||||
set (CMAKE_C_FLAGS "--std=gnu99 ${CMAKE_C_FLAGS}")
|
|
||||||
endif ()
|
|
||||||
else ()
|
|
||||||
set (CMAKE_C_STANDARD 99)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
include_directories(src/include)
|
include_directories(src/include)
|
||||||
|
|
||||||
@ -86,7 +81,7 @@ set(TESTLIB_SOURCES
|
|||||||
src/testlib/testlib.c
|
src/testlib/testlib.c
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SOURCES
|
set(REPL_SOURCES
|
||||||
${ASSEMBLER_SOURCES}
|
${ASSEMBLER_SOURCES}
|
||||||
${COMPILER_SOURCES}
|
${COMPILER_SOURCES}
|
||||||
${CORE_SOURCES}
|
${CORE_SOURCES}
|
||||||
@ -94,6 +89,39 @@ ${MAINCLIENT_SOURCES}
|
|||||||
${PARSER_SOURCES}
|
${PARSER_SOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Set Public headers
|
||||||
|
set(DST_PUBLIC_HEADERS
|
||||||
|
src/include/dst/dst.h
|
||||||
|
src/include/dst/dstasm.h
|
||||||
|
src/include/dst/dstcompile.h
|
||||||
|
src/include/dst/dstconfig.h
|
||||||
|
src/include/dst/dstopcodes.h
|
||||||
|
src/include/dst/dstparse.h
|
||||||
|
src/include/dst/dststate.h
|
||||||
|
src/include/dst/dststl.h
|
||||||
|
src/include/dst/dsttypes.h
|
||||||
|
)
|
||||||
|
|
||||||
# Build the executable
|
# Build the executable
|
||||||
add_executable(${TARGET_NAME} ${SOURCES})
|
add_executable(${TARGET_NAME} ${REPL_SOURCES})
|
||||||
target_link_libraries(${TARGET_NAME} m dl)
|
target_link_libraries(${TARGET_NAME} m dl)
|
||||||
|
set_target_properties(${TARGET_NAME} PROPERTIES PUBLIC_HEADER "${DST_PUBLIC_HEADERS}")
|
||||||
|
|
||||||
|
# Install
|
||||||
|
install(TARGETS ${TARGET_NAME}
|
||||||
|
LIBRARY DESTINATION "lib"
|
||||||
|
RUNTIME DESTINATION "bin"
|
||||||
|
PUBLIC_HEADER DESTINATION "include/dst"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add some test scripts
|
||||||
|
enable_testing()
|
||||||
|
add_test(suite0 ${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/test/suite0.dst)
|
||||||
|
add_test(suite1 ${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/test/suite1.dst)
|
||||||
|
|
||||||
|
# Add convenience script to run repl
|
||||||
|
add_custom_target(run
|
||||||
|
COMMAND ${TARGET_NAME}
|
||||||
|
DEPENDS ${TARGET_NAME}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_PROJECT_DIR}
|
||||||
|
)
|
||||||
|
104
Makefile
104
Makefile
@ -1,104 +0,0 @@
|
|||||||
# Copyright (c) 2017 Calvin Rose
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
# of this software and associated documentation files (the "Software"), to
|
|
||||||
# deal in the Software without restriction, including without limitation the
|
|
||||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
# sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
# furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
# IN THE SOFTWARE.
|
|
||||||
|
|
||||||
################################
|
|
||||||
##### Set global variables #####
|
|
||||||
################################
|
|
||||||
|
|
||||||
PREFIX?=/usr/local
|
|
||||||
BINDIR=$(PREFIX)/bin
|
|
||||||
|
|
||||||
CFLAGS=-std=c99 -Wall -Wextra -Isrc/include -g
|
|
||||||
CLIBS=-lm -ldl
|
|
||||||
PREFIX=/usr/local
|
|
||||||
DST_TARGET=dst
|
|
||||||
DEBUGGER=lldb
|
|
||||||
|
|
||||||
DST_C_LIBS=$(addprefix libs/,testlib.so)
|
|
||||||
|
|
||||||
DST_HEADERS=$(sort $(wildcard src/include/dst/*.h))
|
|
||||||
DST_LIBHEADERS=$(sort $(wildcard src/include/headerlibs/*.h))
|
|
||||||
DST_ALL_HEADERS=$(DST_HEADERS) $(DST_LIB_HEADERS)
|
|
||||||
|
|
||||||
DST_ASM_SOURCES=$(sort $(wildcard src/assembler/*.c))
|
|
||||||
DST_COMPILER_SOURCES=$(sort $(wildcard src/compiler/*.c))
|
|
||||||
DST_CONTEXT_SOURCES=$(sort $(wildcard src/context/*.c))
|
|
||||||
DST_CORE_SOURCES=$(sort $(wildcard src/core/*.c))
|
|
||||||
DST_MAINCLIENT_SOURCES=$(sort $(wildcard src/mainclient/*.c))
|
|
||||||
DST_PARSER_SOURCES=$(sort $(wildcard src/parser/*.c))
|
|
||||||
|
|
||||||
all: $(DST_TARGET)
|
|
||||||
|
|
||||||
########################################
|
|
||||||
##### The main interpreter program #####
|
|
||||||
########################################
|
|
||||||
|
|
||||||
DST_ALL_SOURCES=$(DST_ASM_SOURCES) \
|
|
||||||
$(DST_COMPILER_SOURCES) \
|
|
||||||
$(DST_CONTEXT_SOURCES) \
|
|
||||||
$(DST_CORE_SOURCES) \
|
|
||||||
$(DST_MAINCLIENT_SOURCES) \
|
|
||||||
$(DST_PARSER_SOURCES)
|
|
||||||
|
|
||||||
$(DST_TARGET): $(DST_ALL_SOURCES) $(DST_ALL_HEADERS)
|
|
||||||
$(CC) $(CFLAGS) -o $(DST_TARGET) $(DST_ALL_SOURCES) $(CLIBS)
|
|
||||||
|
|
||||||
#######################
|
|
||||||
##### C Libraries #####
|
|
||||||
#######################
|
|
||||||
|
|
||||||
%.so: %.c $(DST_HEADERS)
|
|
||||||
$(CC) $(CFLAGS) -DDST_LIB -shared -undefined dynamic_lookup -o $@ $<
|
|
||||||
|
|
||||||
###################
|
|
||||||
##### Testing #####
|
|
||||||
###################
|
|
||||||
|
|
||||||
repl: $(DST_TARGET)
|
|
||||||
@ ./$(DST_TARGET)
|
|
||||||
|
|
||||||
debug: $(DST_TARGET)
|
|
||||||
@ $(DEBUGGER) ./$(DST_TARGET)
|
|
||||||
|
|
||||||
valgrind: $(DST_TARGET)
|
|
||||||
@ valgrind --leak-check=full -v ./$(DST_TARGET)
|
|
||||||
|
|
||||||
test: $(DST_TARGET)
|
|
||||||
@ ./$(DST_TARGET) --gcinterval=0x10000 test/suite0.dst
|
|
||||||
|
|
||||||
valtest: $(DST_TARGET)
|
|
||||||
valgrind --leak-check=full -v ./$(DST_TARGET) dsttests/basic.dst
|
|
||||||
|
|
||||||
#################
|
|
||||||
##### Other #####
|
|
||||||
#################
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm $(DST_TARGET) || true
|
|
||||||
rm src/**/*.o || true
|
|
||||||
rm vgcore.* || true
|
|
||||||
|
|
||||||
install: $(DST_TARGET)
|
|
||||||
cp $(DST_TARGET) $(BINDIR)/dst
|
|
||||||
|
|
||||||
uninstall:
|
|
||||||
rm $(BINDIR)/dst
|
|
||||||
|
|
||||||
.PHONY: clean install repl debug valgrind test valtest install uninstall
|
|
33
README.md
33
README.md
@ -2,12 +2,11 @@
|
|||||||
|
|
||||||
[![Build Status](https://travis-ci.org/bakpakin/dst.svg?branch=master)](https://travis-ci.org/bakpakin/dst)
|
[![Build Status](https://travis-ci.org/bakpakin/dst.svg?branch=master)](https://travis-ci.org/bakpakin/dst)
|
||||||
|
|
||||||
dst is a functional programming language and vm. It is a variant of
|
dst is a functional programming language and vm. The language is a lisp that replaces
|
||||||
Lisp with several native useful datatypes. Some of the more interesting and
|
the list with other data structures that have better realworld characteristics and performance.
|
||||||
useful features are first class functions and closures, immutable and mutable
|
The language can also easily bridge to native code, and
|
||||||
hashtables, arrays, and bytebuffers, macros, tail-call optimization,
|
native useful datatypes. The bytecode vm is a register based vm loosely inspired
|
||||||
and continuations. The runtime and
|
by the LuaJIT bytecode format.
|
||||||
compiler are written in C99.
|
|
||||||
|
|
||||||
There is a repl for trying out the language, as well as the ability
|
There is a repl for trying out the language, as well as the ability
|
||||||
to run script files. This client program is separate from the core runtime, so
|
to run script files. This client program is separate from the core runtime, so
|
||||||
@ -22,20 +21,32 @@ dst could be embedded into other programs.
|
|||||||
* Mutable and immutable arrays (array/tuple)
|
* Mutable and immutable arrays (array/tuple)
|
||||||
* Mutable and immutable hashtables (table/struct)
|
* Mutable and immutable hashtables (table/struct)
|
||||||
* Mutable and immutable strings (buffer/string)
|
* Mutable and immutable strings (buffer/string)
|
||||||
|
* Lisp Macros
|
||||||
* Byte code interpreter with an assembly interface, as well as bytecode verification
|
* Byte code interpreter with an assembly interface, as well as bytecode verification
|
||||||
* Proper tail calls for functional code
|
* Proper tail calls.
|
||||||
* Direct interop with C via abstract types and C functions
|
* Direct interop with C via abstract types and C functions
|
||||||
* Dynamically load C libraries
|
* Dynamically load C libraries
|
||||||
* REPL (read eval print loop)
|
* REPL
|
||||||
|
|
||||||
## Compiling and Running
|
## Compiling and Running
|
||||||
|
|
||||||
To build the runtime and run test, run
|
Dst is built using CMake. There used to be a hand-written Makefile, but in the interest of
|
||||||
|
easier Windows support I have switched to CMake.
|
||||||
|
|
||||||
|
On a posix system using make, compiling and running is as follows (this is the same as
|
||||||
|
most CMake based projects).
|
||||||
|
|
||||||
|
### Build
|
||||||
```sh
|
```sh
|
||||||
|
cd somewhere/my/projects/dst
|
||||||
|
mkdir -p build
|
||||||
|
cd build
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||||
|
make
|
||||||
make test
|
make test
|
||||||
```
|
```
|
||||||
|
|
||||||
A repl can also be run with
|
The repl can also be run with the CMake run target.
|
||||||
```sh
|
```sh
|
||||||
make repl
|
make run
|
||||||
```
|
```
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
typedef struct DstInstructionDef DstInstructionDef;
|
typedef struct DstInstructionDef DstInstructionDef;
|
||||||
struct DstInstructionDef {
|
struct DstInstructionDef {
|
||||||
const char *name;
|
const char *name;
|
||||||
DstOpCode opcode;
|
enum DstOpCode opcode;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Hold all state needed during assembly */
|
/* Hold all state needed during assembly */
|
||||||
@ -216,7 +216,7 @@ static int32_t dst_asm_addenv(DstAssembler *a, Dst envname) {
|
|||||||
* integer. This integer will need to be bounds checked. */
|
* integer. This integer will need to be bounds checked. */
|
||||||
static int32_t doarg_1(
|
static int32_t doarg_1(
|
||||||
DstAssembler *a,
|
DstAssembler *a,
|
||||||
DstOpArgType argtype,
|
enum DstOpArgType argtype,
|
||||||
Dst x) {
|
Dst x) {
|
||||||
int32_t ret = -1;
|
int32_t ret = -1;
|
||||||
DstTable *c;
|
DstTable *c;
|
||||||
@ -311,7 +311,7 @@ static int32_t doarg_1(
|
|||||||
* try to convert arguments to bit patterns */
|
* try to convert arguments to bit patterns */
|
||||||
static uint32_t doarg(
|
static uint32_t doarg(
|
||||||
DstAssembler *a,
|
DstAssembler *a,
|
||||||
DstOpArgType argtype,
|
enum DstOpArgType argtype,
|
||||||
int nth,
|
int nth,
|
||||||
int nbytes,
|
int nbytes,
|
||||||
int hassign,
|
int hassign,
|
||||||
@ -336,7 +336,7 @@ static uint32_t read_instruction(
|
|||||||
const DstInstructionDef *idef,
|
const DstInstructionDef *idef,
|
||||||
const Dst *argt) {
|
const Dst *argt) {
|
||||||
uint32_t instr = idef->opcode;
|
uint32_t instr = idef->opcode;
|
||||||
DstInstructionType type = dst_instructions[idef->opcode];
|
enum DstInstructionType type = dst_instructions[idef->opcode];
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DIT_0:
|
case DIT_0:
|
||||||
{
|
{
|
||||||
|
@ -241,7 +241,8 @@ DstSlot dstc_resolve(
|
|||||||
if (scope->flags & DST_SCOPE_UNUSED)
|
if (scope->flags & DST_SCOPE_UNUSED)
|
||||||
unused = 1;
|
unused = 1;
|
||||||
len = dst_v_count(scope->syms);
|
len = dst_v_count(scope->syms);
|
||||||
for (i = 0; i < len; i++) {
|
/* Search in reverse order */
|
||||||
|
for (i = len - 1; i >= 0; i--) {
|
||||||
pair = scope->syms + i;
|
pair = scope->syms + i;
|
||||||
if (pair->sym == sym) {
|
if (pair->sym == sym) {
|
||||||
ret = pair->slot;
|
ret = pair->slot;
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#define CHUNKSIZE 1024
|
#define CHUNKSIZE 1024
|
||||||
|
|
||||||
/* Read input for a repl */
|
/* Read input for a repl */
|
||||||
static int replread(DstContext *c, DstParserStatus status) {
|
static int replread(DstContext *c, enum DstParserStatus status) {
|
||||||
if (status == DST_PARSE_PENDING)
|
if (status == DST_PARSE_PENDING)
|
||||||
printf(">> ");
|
printf(">> ");
|
||||||
else
|
else
|
||||||
@ -53,7 +53,7 @@ static void replonvalue(DstContext *c, Dst value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Handle errors on repl */
|
/* Handle errors on repl */
|
||||||
static void simpleerror(DstContext *c, DstContextErrorType type, Dst err, size_t start, size_t end) {
|
static void simpleerror(DstContext *c, enum DstContextErrorType type, Dst err, size_t start, size_t end) {
|
||||||
const char *errtype;
|
const char *errtype;
|
||||||
(void) c;
|
(void) c;
|
||||||
(void) start;
|
(void) start;
|
||||||
@ -76,7 +76,7 @@ static void filedeinit(DstContext *c) {
|
|||||||
fclose((FILE *) (c->user));
|
fclose((FILE *) (c->user));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fileread(DstContext *c, DstParserStatus status) {
|
static int fileread(DstContext *c, enum DstParserStatus status) {
|
||||||
size_t nread;
|
size_t nread;
|
||||||
FILE *f = (FILE *) c->user;
|
FILE *f = (FILE *) c->user;
|
||||||
(void) status;
|
(void) status;
|
||||||
@ -132,7 +132,7 @@ int dst_context_file(DstContext *c, DstTable *env, const char *path) {
|
|||||||
/* Do something on an error. Return flags to or with current flags. */
|
/* Do something on an error. Return flags to or with current flags. */
|
||||||
static int doerror(
|
static int doerror(
|
||||||
DstContext *c,
|
DstContext *c,
|
||||||
DstContextErrorType type,
|
enum DstContextErrorType type,
|
||||||
Dst err,
|
Dst err,
|
||||||
int32_t bstart,
|
int32_t bstart,
|
||||||
int32_t bend) {
|
int32_t bend) {
|
||||||
@ -150,7 +150,7 @@ int dst_context_run(DstContext *c, int flags) {
|
|||||||
int done = 0;
|
int done = 0;
|
||||||
int errflags = 0;
|
int errflags = 0;
|
||||||
DstParser parser;
|
DstParser parser;
|
||||||
DstParserStatus status;
|
enum DstParserStatus status;
|
||||||
dst_parser_init(&parser, flags);
|
dst_parser_init(&parser, flags);
|
||||||
while (!done) {
|
while (!done) {
|
||||||
int bufferdone = 0;
|
int bufferdone = 0;
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "gc.h"
|
#include "gc.h"
|
||||||
|
|
||||||
/* Look up table for instructions */
|
/* Look up table for instructions */
|
||||||
DstInstructionType dst_instructions[DOP_INSTRUCTION_COUNT] = {
|
enum DstInstructionType dst_instructions[DOP_INSTRUCTION_COUNT] = {
|
||||||
DIT_0, /* DOP_NOOP, */
|
DIT_0, /* DOP_NOOP, */
|
||||||
DIT_S, /* DOP_ERROR, */
|
DIT_S, /* DOP_ERROR, */
|
||||||
DIT_ST, /* DOP_TYPECHECK, */
|
DIT_ST, /* DOP_TYPECHECK, */
|
||||||
@ -106,7 +106,7 @@ int32_t dst_verify(DstFuncDef *def) {
|
|||||||
if ((instr & 0xFF) >= DOP_INSTRUCTION_COUNT) {
|
if ((instr & 0xFF) >= DOP_INSTRUCTION_COUNT) {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
DstInstructionType type = dst_instructions[instr & 0xFF];
|
enum DstInstructionType type = dst_instructions[instr & 0xFF];
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DIT_0:
|
case DIT_0:
|
||||||
continue;
|
continue;
|
||||||
|
@ -30,7 +30,6 @@ extern "C" {
|
|||||||
#include "dsttypes.h"
|
#include "dsttypes.h"
|
||||||
|
|
||||||
/* Assembly */
|
/* Assembly */
|
||||||
typedef enum DstAssembleStatus DstAssembleStatus;
|
|
||||||
typedef struct DstAssembleResult DstAssembleResult;
|
typedef struct DstAssembleResult DstAssembleResult;
|
||||||
typedef struct DstAssembleOptions DstAssembleOptions;
|
typedef struct DstAssembleOptions DstAssembleOptions;
|
||||||
enum DstAssembleStatus {
|
enum DstAssembleStatus {
|
||||||
@ -40,7 +39,7 @@ enum DstAssembleStatus {
|
|||||||
struct DstAssembleResult {
|
struct DstAssembleResult {
|
||||||
DstFuncDef *funcdef;
|
DstFuncDef *funcdef;
|
||||||
const uint8_t *error;
|
const uint8_t *error;
|
||||||
DstAssembleStatus status;
|
enum DstAssembleStatus status;
|
||||||
};
|
};
|
||||||
DstAssembleResult dst_asm(Dst source, int flags);
|
DstAssembleResult dst_asm(Dst source, int flags);
|
||||||
Dst dst_disasm(DstFuncDef *def);
|
Dst dst_disasm(DstFuncDef *def);
|
||||||
|
@ -30,7 +30,6 @@ extern "C" {
|
|||||||
#include "dsttypes.h"
|
#include "dsttypes.h"
|
||||||
#include "dstparse.h"
|
#include "dstparse.h"
|
||||||
|
|
||||||
typedef enum DstCompileStatus DstCompileStatus;
|
|
||||||
typedef struct DstCompileOptions DstCompileOptions;
|
typedef struct DstCompileOptions DstCompileOptions;
|
||||||
typedef struct DstCompileResult DstCompileResult;
|
typedef struct DstCompileResult DstCompileResult;
|
||||||
enum DstCompileStatus {
|
enum DstCompileStatus {
|
||||||
@ -38,7 +37,7 @@ enum DstCompileStatus {
|
|||||||
DST_COMPILE_ERROR
|
DST_COMPILE_ERROR
|
||||||
};
|
};
|
||||||
struct DstCompileResult {
|
struct DstCompileResult {
|
||||||
DstCompileStatus status;
|
enum DstCompileStatus status;
|
||||||
DstFuncDef *funcdef;
|
DstFuncDef *funcdef;
|
||||||
const uint8_t *error;
|
const uint8_t *error;
|
||||||
int32_t error_start;
|
int32_t error_start;
|
||||||
@ -57,11 +56,11 @@ int dst_context_file(DstContext *c, DstTable *env, const char *path);
|
|||||||
int dst_context_run(DstContext *c, int flags);
|
int dst_context_run(DstContext *c, int flags);
|
||||||
|
|
||||||
/* Parse structs */
|
/* Parse structs */
|
||||||
typedef enum {
|
enum DstContextErrorType {
|
||||||
DST_CONTEXT_ERROR_PARSE,
|
DST_CONTEXT_ERROR_PARSE,
|
||||||
DST_CONTEXT_ERROR_COMPILE,
|
DST_CONTEXT_ERROR_COMPILE,
|
||||||
DST_CONTEXT_ERROR_RUNTIME
|
DST_CONTEXT_ERROR_RUNTIME
|
||||||
} DstContextErrorType;
|
};
|
||||||
|
|
||||||
/* Evaluation context. Encapsulates parsing and compiling for easier integration
|
/* Evaluation context. Encapsulates parsing and compiling for easier integration
|
||||||
* with client programs. */
|
* with client programs. */
|
||||||
@ -71,8 +70,8 @@ struct DstContext {
|
|||||||
void *user;
|
void *user;
|
||||||
int32_t index;
|
int32_t index;
|
||||||
|
|
||||||
int (*read_chunk)(DstContext *self, DstParserStatus status);
|
int (*read_chunk)(DstContext *self, enum DstParserStatus status);
|
||||||
void (*on_error)(DstContext *self, DstContextErrorType type, Dst err, size_t start, size_t end);
|
void (*on_error)(DstContext *self, enum DstContextErrorType type, Dst err, size_t start, size_t end);
|
||||||
void (*on_value)(DstContext *self, Dst value);
|
void (*on_value)(DstContext *self, Dst value);
|
||||||
void (*deinit)(DstContext *self);
|
void (*deinit)(DstContext *self);
|
||||||
};
|
};
|
||||||
|
@ -28,7 +28,6 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Bytecode op argument types */
|
/* Bytecode op argument types */
|
||||||
typedef enum DstOpArgType DstOpArgType;
|
|
||||||
enum DstOpArgType {
|
enum DstOpArgType {
|
||||||
DST_OAT_SLOT,
|
DST_OAT_SLOT,
|
||||||
DST_OAT_ENVIRONMENT,
|
DST_OAT_ENVIRONMENT,
|
||||||
@ -41,7 +40,6 @@ enum DstOpArgType {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Various types of instructions */
|
/* Various types of instructions */
|
||||||
typedef enum DstInstructionType DstInstructionType;
|
|
||||||
enum DstInstructionType {
|
enum DstInstructionType {
|
||||||
DIT_0, /* No args */
|
DIT_0, /* No args */
|
||||||
DIT_S, /* Slot(3) */
|
DIT_S, /* Slot(3) */
|
||||||
@ -59,7 +57,6 @@ enum DstInstructionType {
|
|||||||
DIT_SC /* Slot(1), Constant(2) */
|
DIT_SC /* Slot(1), Constant(2) */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum DstOpCode DstOpCode;
|
|
||||||
enum DstOpCode {
|
enum DstOpCode {
|
||||||
DOP_NOOP,
|
DOP_NOOP,
|
||||||
DOP_ERROR,
|
DOP_ERROR,
|
||||||
@ -125,7 +122,7 @@ enum DstOpCode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Info about all instructions */
|
/* Info about all instructions */
|
||||||
extern DstInstructionType dst_instructions[DOP_INSTRUCTION_COUNT];
|
extern enum DstInstructionType dst_instructions[DOP_INSTRUCTION_COUNT];
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ extern "C" {
|
|||||||
|
|
||||||
#include "dsttypes.h"
|
#include "dsttypes.h"
|
||||||
|
|
||||||
typedef enum DstParserStatus DstParserStatus;
|
|
||||||
typedef struct DstParseState DstParseState;
|
typedef struct DstParseState DstParseState;
|
||||||
typedef struct DstParser DstParser;
|
typedef struct DstParser DstParser;
|
||||||
|
|
||||||
@ -60,7 +59,7 @@ struct DstParser {
|
|||||||
void dst_parser_init(DstParser *parser, int flags);
|
void dst_parser_init(DstParser *parser, int flags);
|
||||||
void dst_parser_deinit(DstParser *parser);
|
void dst_parser_deinit(DstParser *parser);
|
||||||
int dst_parser_consume(DstParser *parser, uint8_t c);
|
int dst_parser_consume(DstParser *parser, uint8_t c);
|
||||||
DstParserStatus dst_parser_status(DstParser *parser);
|
enum DstParserStatus dst_parser_status(DstParser *parser);
|
||||||
Dst dst_parser_produce(DstParser *parser);
|
Dst dst_parser_produce(DstParser *parser);
|
||||||
const char *dst_parser_error(DstParser *parser);
|
const char *dst_parser_error(DstParser *parser);
|
||||||
int dst_parse_cfun(DstArgs args);
|
int dst_parse_cfun(DstArgs args);
|
||||||
|
@ -33,9 +33,10 @@ static const void *dst_strbinsearch(
|
|||||||
const uint8_t *key) {
|
const uint8_t *key) {
|
||||||
size_t low = 0;
|
size_t low = 0;
|
||||||
size_t hi = tabcount;
|
size_t hi = tabcount;
|
||||||
|
const char *t = (const char *)tab;
|
||||||
while (low < hi) {
|
while (low < hi) {
|
||||||
size_t mid = low + ((hi - low) / 2);
|
size_t mid = low + ((hi - low) / 2);
|
||||||
const char **item = (const char **)(tab + mid * itemsize);
|
const char **item = (const char **)(t + mid * itemsize);
|
||||||
const char *name = *item;
|
const char *name = *item;
|
||||||
int comp = dst_cstrcmp(key, name);
|
int comp = dst_cstrcmp(key, name);
|
||||||
if (comp < 0) {
|
if (comp < 0) {
|
||||||
|
@ -79,7 +79,7 @@ int main(int argc, char **argv) {
|
|||||||
} else {
|
} else {
|
||||||
flags |= DST_CLIENT_UNKNOWN;
|
flags |= DST_CLIENT_UNKNOWN;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (*arg) {
|
||||||
/* Flag */
|
/* Flag */
|
||||||
const char *c = arg;
|
const char *c = arg;
|
||||||
while (*(++c)) {
|
while (*(++c)) {
|
||||||
@ -139,9 +139,10 @@ int main(int argc, char **argv) {
|
|||||||
fileRead = 1;
|
fileRead = 1;
|
||||||
if (dst_context_file(&ctxt, env, arg)) {
|
if (dst_context_file(&ctxt, env, arg)) {
|
||||||
printf("file %s not found\n", arg);
|
printf("file %s not found\n", arg);
|
||||||
|
status |= 2;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
status = dst_context_run(&ctxt, DST_PARSEFLAG_SOURCEMAP);
|
status |= dst_context_run(&ctxt, DST_PARSEFLAG_SOURCEMAP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,7 +464,7 @@ int dst_parser_consume(DstParser *parser, uint8_t c) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
DstParserStatus dst_parser_status(DstParser *parser) {
|
enum DstParserStatus dst_parser_status(DstParser *parser) {
|
||||||
if (parser->error) return DST_PARSE_ERROR;
|
if (parser->error) return DST_PARSE_ERROR;
|
||||||
if (dst_v_count(parser->states) > 1) return DST_PARSE_PENDING;
|
if (dst_v_count(parser->states) > 1) return DST_PARSE_PENDING;
|
||||||
if (dst_v_count(parser->argstack)) return DST_PARSE_FULL;
|
if (dst_v_count(parser->argstack)) return DST_PARSE_FULL;
|
||||||
@ -472,7 +472,7 @@ DstParserStatus dst_parser_status(DstParser *parser) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *dst_parser_error(DstParser *parser) {
|
const char *dst_parser_error(DstParser *parser) {
|
||||||
DstParserStatus status = dst_parser_status(parser);
|
enum DstParserStatus status = dst_parser_status(parser);
|
||||||
if (status == DST_PARSE_ERROR) {
|
if (status == DST_PARSE_ERROR) {
|
||||||
const char *e = parser->error;
|
const char *e = parser->error;
|
||||||
dst_v_empty(parser->argstack);
|
dst_v_empty(parser->argstack);
|
||||||
@ -487,7 +487,7 @@ const char *dst_parser_error(DstParser *parser) {
|
|||||||
Dst dst_parser_produce(DstParser *parser) {
|
Dst dst_parser_produce(DstParser *parser) {
|
||||||
Dst ret;
|
Dst ret;
|
||||||
int32_t i;
|
int32_t i;
|
||||||
DstParserStatus status = dst_parser_status(parser);
|
enum DstParserStatus status = dst_parser_status(parser);
|
||||||
if (status != DST_PARSE_FULL) return dst_wrap_nil();
|
if (status != DST_PARSE_FULL) return dst_wrap_nil();
|
||||||
ret = parser->argstack[0];
|
ret = parser->argstack[0];
|
||||||
for (i = 1; i < dst_v_count(parser->argstack); i++) {
|
for (i = 1; i < dst_v_count(parser->argstack); i++) {
|
||||||
|
76
test/boot.dst
Normal file
76
test/boot.dst
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# Copyright (c) 2017 Calvin Rose
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to
|
||||||
|
# deal in the Software without restriction, including without limitation the
|
||||||
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
# sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
# IN THE SOFTWARE.
|
||||||
|
|
||||||
|
# Bootstrap the language
|
||||||
|
|
||||||
|
(def defmacro macro (fn [name & more]
|
||||||
|
(tuple 'def name 'macro (tuple-prepend (tuple-prepend more name) 'fn))))
|
||||||
|
(defmacro defn
|
||||||
|
[name & more]
|
||||||
|
(tuple 'def name
|
||||||
|
(tuple-prepend (tuple-prepend more name) 'fn)))
|
||||||
|
|
||||||
|
(defmacro when [cond & body] (tuple 'if cond (tuple-prepend body 'do)))
|
||||||
|
|
||||||
|
(defn array-seq [x]
|
||||||
|
(def len (length x))
|
||||||
|
(var i 0)
|
||||||
|
{
|
||||||
|
:more (fn [] (< i len))
|
||||||
|
:next (fn []
|
||||||
|
(def ret (get x i))
|
||||||
|
(varset! i (+ i 1))
|
||||||
|
ret)
|
||||||
|
})
|
||||||
|
|
||||||
|
(def seqs {
|
||||||
|
:array array-seq
|
||||||
|
:tuple array-seq
|
||||||
|
:struct (fn [x] x)})
|
||||||
|
|
||||||
|
(defn seq [x]
|
||||||
|
(def makeseq (get seqs (type x)))
|
||||||
|
(if makeseq (makeseq x) (error "expected sequence")))
|
||||||
|
|
||||||
|
(defn range [top]
|
||||||
|
(var i 0)
|
||||||
|
{
|
||||||
|
:more (fn [] (< i top))
|
||||||
|
:next (fn []
|
||||||
|
(def ret i)
|
||||||
|
(varset! i (+ i 1))
|
||||||
|
i)
|
||||||
|
})
|
||||||
|
|
||||||
|
(defn doseq [s f]
|
||||||
|
(def s (seq s))
|
||||||
|
(def more? (get s :more))
|
||||||
|
(def getnext (get s :next))
|
||||||
|
(while (more?)
|
||||||
|
(f (getnext))))
|
||||||
|
|
||||||
|
(defn map [f s]
|
||||||
|
(def s (seq s))
|
||||||
|
(def more (get s :more))
|
||||||
|
(def getnext (get s :next))
|
||||||
|
{
|
||||||
|
:more more
|
||||||
|
:next (f (getnext))
|
||||||
|
})
|
@ -1,67 +0,0 @@
|
|||||||
# A .dsts file will contain VM, assembly for a dst function. This includes
|
|
||||||
# associated constants and what not. The assembler should be able to
|
|
||||||
# simply construct a FuncDef from this file. This file is also parsed
|
|
||||||
# in the same markup as dst itself (extended S expressions)
|
|
||||||
{
|
|
||||||
arity 3
|
|
||||||
source "source file path"
|
|
||||||
vararg false
|
|
||||||
# Name for reference by nested funcdefs
|
|
||||||
name outerfunc
|
|
||||||
# Contains the bytecode for this function. This can be assembly
|
|
||||||
# instructions or integers. Assembly will be converted to integer bytecodes immediately.
|
|
||||||
bytecode [
|
|
||||||
(load-constant 0 bork)
|
|
||||||
(load-constant 1 bip)
|
|
||||||
(add 0 0 1)
|
|
||||||
(add-immediate 0 0 127)
|
|
||||||
(push3 0 0 0)
|
|
||||||
(push3 0 0 0)
|
|
||||||
(push3 0 0 0)
|
|
||||||
(syscall 1 0)
|
|
||||||
(return 0)
|
|
||||||
]
|
|
||||||
# A source map is optional. The sourcemap corresponds with the byte code.
|
|
||||||
# Each instruction has two source map entries, offset start and offset end.
|
|
||||||
# map [
|
|
||||||
# 1
|
|
||||||
# 2
|
|
||||||
# 3
|
|
||||||
# 10
|
|
||||||
# 15
|
|
||||||
# 39
|
|
||||||
# 90
|
|
||||||
# 134
|
|
||||||
# ...
|
|
||||||
# ]
|
|
||||||
#
|
|
||||||
# The number of slots available for the function.
|
|
||||||
# Slots can be named as well for convenience.
|
|
||||||
slots [
|
|
||||||
x
|
|
||||||
y
|
|
||||||
z
|
|
||||||
]
|
|
||||||
# Captured outer environments that are referenced
|
|
||||||
captures [ ]
|
|
||||||
# Constants are an array or tuple. For named constants, use a tuple that begins with let
|
|
||||||
# For a literal tuple, use (quote tuple), or 'tuple. Without names, constants must be indexed
|
|
||||||
# from their number
|
|
||||||
# Literal FuncEnvs and Functions may be possible later
|
|
||||||
constants [
|
|
||||||
:hello
|
|
||||||
(def bork 123)
|
|
||||||
(def bip 456)
|
|
||||||
'(1 2 3)
|
|
||||||
(def atuple (1 2 3))
|
|
||||||
(567)
|
|
||||||
]
|
|
||||||
# Arbitrary meta data can be added to the source
|
|
||||||
my-meta-2 @{
|
|
||||||
1 2 3 4
|
|
||||||
}
|
|
||||||
my-meta {
|
|
||||||
1 2 3 4 5 6 7 8 9 0 11 12 13 14
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
(print "Hello, World!")
|
|
@ -1,26 +0,0 @@
|
|||||||
# A fairly minimal example of a dst assembly file
|
|
||||||
{
|
|
||||||
bytecode [
|
|
||||||
(load-integer 0 15)
|
|
||||||
(load-integer 1 0)
|
|
||||||
(load-constant 3 lookup)
|
|
||||||
|
|
||||||
:label
|
|
||||||
(equals 2 1 0)
|
|
||||||
(jump-if 2 :done)
|
|
||||||
(add-immediate 0 0 -1)
|
|
||||||
(get 2 3 0)
|
|
||||||
(push 2)
|
|
||||||
(syscall 2 0)
|
|
||||||
(jump :label)
|
|
||||||
|
|
||||||
:done
|
|
||||||
(return-nil)
|
|
||||||
|
|
||||||
:extra
|
|
||||||
(push 2)
|
|
||||||
]
|
|
||||||
constants [
|
|
||||||
(def lookup "0123456789abcdef")
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
# Bootstrap the language
|
|
||||||
|
|
||||||
# Helper for macro expansion
|
|
||||||
(def macroexpand (fn recur [x]
|
|
||||||
(def y (ast-unwrap x))
|
|
||||||
(if (= (type y) :tuple)
|
|
||||||
(if (> (length y) 0)
|
|
||||||
(do
|
|
||||||
(def first (get y 0))
|
|
||||||
(def rest (array-slice y 1))
|
|
||||||
(def macro (get _env first))
|
|
||||||
(if macro (recur (apply macro rest)) x))
|
|
||||||
x)
|
|
||||||
x)))
|
|
@ -1,34 +0,0 @@
|
|||||||
(def mapnil
|
|
||||||
" (mapnil f a)
|
|
||||||
Map a function over a tuple or array and return nil."
|
|
||||||
(fn [f t]
|
|
||||||
(var i 0)
|
|
||||||
(def len (length t))
|
|
||||||
(while (< i len)
|
|
||||||
(f (get t i))
|
|
||||||
(varset! i (+ i 1)))))
|
|
||||||
|
|
||||||
(def mapt
|
|
||||||
" (mapt f t)
|
|
||||||
Map a function over a tuple or array and produce a new tuple."
|
|
||||||
(fn [f t]
|
|
||||||
(var i 0)
|
|
||||||
(def len (length t))
|
|
||||||
(def accum [])
|
|
||||||
(while (< i len)
|
|
||||||
(array-push accum (f (get t i)))
|
|
||||||
(varset! i (+ i 1)))
|
|
||||||
(apply tuple accum)))
|
|
||||||
|
|
||||||
(def mapa
|
|
||||||
" (mapa f a)
|
|
||||||
Map a function over a tuple or array and produce a new array."
|
|
||||||
(fn [f t]
|
|
||||||
(var i 0)
|
|
||||||
(def len (length t))
|
|
||||||
(def accum [])
|
|
||||||
(while (< i len)
|
|
||||||
(array-push accum (f (get t i)))
|
|
||||||
(varset! i (+ i 1)))
|
|
||||||
accum))
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
|||||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
# IN THE SOFTWARE.
|
# IN THE SOFTWARE.
|
||||||
|
|
||||||
(print "\nRunning basic tests...\n")
|
(print "\nRunning Suite 0 tests...\n")
|
||||||
|
|
||||||
(var num-tests-passed 0)
|
(var num-tests-passed 0)
|
||||||
(var num-tests-run 0)
|
(var num-tests-run 0)
|
||||||
|
24
test/suite1.dst
Normal file
24
test/suite1.dst
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Copyright (c) 2017 Calvin Rose
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to
|
||||||
|
# deal in the Software without restriction, including without limitation the
|
||||||
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
# sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
# IN THE SOFTWARE.
|
||||||
|
|
||||||
|
(print "\nRunning Suite 1 Tests...\n")
|
||||||
|
|
||||||
|
(if (not= 400.0 (sqrt 160000)) (error "sqrt(160000)=400"))
|
||||||
|
(if (not= (real 400) (sqrt 160000)) (error "sqrt(160000)=400"))
|
Loading…
Reference in New Issue
Block a user