mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 15:43:01 +00:00 
			
		
		
		
	Switch over to Cmake fully.
This commit is contained in:
		| @@ -1,6 +1,11 @@ | ||||
| language: c | ||||
|  | ||||
| script: make test | ||||
| script: | ||||
|   - mkdir -p build | ||||
|   - cd build | ||||
|   - cmake ..  | ||||
|   - make | ||||
|   - make test | ||||
|  | ||||
| compiler: | ||||
|   - clang | ||||
|   | ||||
| @@ -18,18 +18,13 @@ | ||||
| # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||||
| # IN THE SOFTWARE. | ||||
|  | ||||
| cmake_minimum_required(VERSION 3.9) | ||||
| cmake_minimum_required(VERSION 3.7) | ||||
| project(dst) | ||||
|  | ||||
| # Set Some Variables | ||||
| set(TARGET_NAME ${PROJECT_NAME}) | ||||
| if (CMAKE_VERSION VERSION_LESS "3.1") | ||||
|     if (CMAKE_C_COMPILER_ID STREQUAL "GNU") | ||||
|         set (CMAKE_C_FLAGS "--std=gnu99 ${CMAKE_C_FLAGS}") | ||||
|     endif () | ||||
| else () | ||||
|     set (CMAKE_C_STANDARD 99) | ||||
| endif () | ||||
| set (CMAKE_C_STANDARD 99) | ||||
| set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra") | ||||
|  | ||||
| include_directories(src/include) | ||||
|  | ||||
| @@ -86,7 +81,7 @@ set(TESTLIB_SOURCES | ||||
| src/testlib/testlib.c | ||||
| ) | ||||
|  | ||||
| set(SOURCES | ||||
| set(REPL_SOURCES | ||||
| ${ASSEMBLER_SOURCES} | ||||
| ${COMPILER_SOURCES} | ||||
| ${CORE_SOURCES} | ||||
| @@ -94,6 +89,39 @@ ${MAINCLIENT_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 | ||||
| add_executable(${TARGET_NAME} ${SOURCES}) | ||||
| add_executable(${TARGET_NAME} ${REPL_SOURCES}) | ||||
| 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 @@ | ||||
|  | ||||
| [](https://travis-ci.org/bakpakin/dst) | ||||
|  | ||||
| dst is a functional programming language and vm. It is a variant of | ||||
| Lisp with several native useful datatypes. Some of the more interesting and | ||||
| useful features are first class functions and closures, immutable and mutable | ||||
| hashtables, arrays, and bytebuffers, macros, tail-call optimization, | ||||
| and continuations. The runtime and  | ||||
| compiler are written in C99. | ||||
| dst is a functional programming language and vm. The language is a lisp that replaces | ||||
| the list with other data structures that have better realworld characteristics and performance. | ||||
| The language can also easily bridge to native code, and  | ||||
| native useful datatypes. The bytecode vm is a register based vm loosely inspired | ||||
| by the LuaJIT bytecode format.  | ||||
|  | ||||
| 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 | ||||
| @@ -22,20 +21,32 @@ dst could be embedded into other programs. | ||||
| * Mutable and immutable arrays (array/tuple) | ||||
| * Mutable and immutable hashtables (table/struct) | ||||
| * Mutable and immutable strings (buffer/string) | ||||
| * Lisp Macros | ||||
| * 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 | ||||
| * Dynamically load C libraries | ||||
| * REPL (read eval print loop) | ||||
| * REPL | ||||
|  | ||||
| ## 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 | ||||
| cd somewhere/my/projects/dst | ||||
| mkdir -p build | ||||
| cd build | ||||
| cmake -DCMAKE_BUILD_TYPE=Release .. | ||||
| make | ||||
| make test | ||||
| ``` | ||||
|  | ||||
| A repl can also be run with | ||||
| The repl can also be run with the CMake run target. | ||||
| ```sh | ||||
| make repl | ||||
| make run | ||||
| ``` | ||||
|   | ||||
| @@ -46,7 +46,7 @@ | ||||
| typedef struct DstInstructionDef DstInstructionDef; | ||||
| struct DstInstructionDef { | ||||
|     const char *name; | ||||
|     DstOpCode opcode; | ||||
|     enum DstOpCode opcode; | ||||
| }; | ||||
|  | ||||
| /* 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. */ | ||||
| static int32_t doarg_1( | ||||
|         DstAssembler *a, | ||||
|         DstOpArgType argtype, | ||||
|         enum DstOpArgType argtype, | ||||
|         Dst x) { | ||||
|     int32_t ret = -1; | ||||
|     DstTable *c; | ||||
| @@ -311,7 +311,7 @@ static int32_t doarg_1( | ||||
|  * try to convert arguments to bit patterns */ | ||||
| static uint32_t doarg( | ||||
|         DstAssembler *a, | ||||
|         DstOpArgType argtype, | ||||
|         enum DstOpArgType argtype, | ||||
|         int nth, | ||||
|         int nbytes, | ||||
|         int hassign, | ||||
| @@ -336,7 +336,7 @@ static uint32_t read_instruction( | ||||
|         const DstInstructionDef *idef, | ||||
|         const Dst *argt) { | ||||
|     uint32_t instr = idef->opcode; | ||||
|     DstInstructionType type = dst_instructions[idef->opcode]; | ||||
|     enum DstInstructionType type = dst_instructions[idef->opcode]; | ||||
|     switch (type) { | ||||
|         case DIT_0: | ||||
|         { | ||||
|   | ||||
| @@ -241,7 +241,8 @@ DstSlot dstc_resolve( | ||||
|         if (scope->flags & DST_SCOPE_UNUSED) | ||||
|             unused = 1; | ||||
|         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; | ||||
|             if (pair->sym == sym) { | ||||
|                 ret = pair->slot; | ||||
|   | ||||
| @@ -27,7 +27,7 @@ | ||||
| #define CHUNKSIZE 1024 | ||||
|  | ||||
| /* 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) | ||||
|         printf(">> "); | ||||
|     else | ||||
| @@ -53,7 +53,7 @@ static void replonvalue(DstContext *c, Dst value) { | ||||
| } | ||||
|  | ||||
| /* 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; | ||||
|     (void) c; | ||||
|     (void) start; | ||||
| @@ -76,7 +76,7 @@ static void filedeinit(DstContext *c) { | ||||
|     fclose((FILE *) (c->user)); | ||||
| } | ||||
|  | ||||
| static int fileread(DstContext *c, DstParserStatus status) { | ||||
| static int fileread(DstContext *c, enum DstParserStatus status) { | ||||
|     size_t nread; | ||||
|     FILE *f = (FILE *) c->user; | ||||
|     (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. */ | ||||
| static int doerror( | ||||
|         DstContext *c, | ||||
|         DstContextErrorType type, | ||||
|         enum DstContextErrorType type, | ||||
|         Dst err, | ||||
|         int32_t bstart, | ||||
|         int32_t bend) { | ||||
| @@ -150,7 +150,7 @@ int dst_context_run(DstContext *c, int flags) { | ||||
|     int done = 0; | ||||
|     int errflags = 0; | ||||
|     DstParser parser; | ||||
|     DstParserStatus status; | ||||
|     enum DstParserStatus status; | ||||
|     dst_parser_init(&parser, flags); | ||||
|     while (!done) { | ||||
|         int bufferdone = 0; | ||||
|   | ||||
| @@ -25,7 +25,7 @@ | ||||
| #include "gc.h" | ||||
|  | ||||
| /* Look up table for instructions */ | ||||
| DstInstructionType dst_instructions[DOP_INSTRUCTION_COUNT] = { | ||||
| enum DstInstructionType dst_instructions[DOP_INSTRUCTION_COUNT] = { | ||||
|     DIT_0, /* DOP_NOOP, */ | ||||
|     DIT_S, /* DOP_ERROR, */ | ||||
|     DIT_ST, /* DOP_TYPECHECK, */ | ||||
| @@ -106,7 +106,7 @@ int32_t dst_verify(DstFuncDef *def) { | ||||
|         if ((instr & 0xFF) >= DOP_INSTRUCTION_COUNT) { | ||||
|             return 3; | ||||
|         } | ||||
|         DstInstructionType type = dst_instructions[instr & 0xFF]; | ||||
|         enum DstInstructionType type = dst_instructions[instr & 0xFF]; | ||||
|         switch (type) { | ||||
|             case DIT_0: | ||||
|                 continue; | ||||
|   | ||||
| @@ -30,7 +30,6 @@ extern "C" { | ||||
| #include "dsttypes.h" | ||||
|  | ||||
| /* Assembly */ | ||||
| typedef enum DstAssembleStatus DstAssembleStatus; | ||||
| typedef struct DstAssembleResult DstAssembleResult; | ||||
| typedef struct DstAssembleOptions DstAssembleOptions; | ||||
| enum DstAssembleStatus { | ||||
| @@ -40,7 +39,7 @@ enum DstAssembleStatus { | ||||
| struct DstAssembleResult { | ||||
|     DstFuncDef *funcdef; | ||||
|     const uint8_t *error; | ||||
|     DstAssembleStatus status; | ||||
|     enum DstAssembleStatus status; | ||||
| }; | ||||
| DstAssembleResult dst_asm(Dst source, int flags); | ||||
| Dst dst_disasm(DstFuncDef *def); | ||||
|   | ||||
| @@ -30,7 +30,6 @@ extern "C" { | ||||
| #include "dsttypes.h" | ||||
| #include "dstparse.h" | ||||
|  | ||||
| typedef enum DstCompileStatus DstCompileStatus; | ||||
| typedef struct DstCompileOptions DstCompileOptions; | ||||
| typedef struct DstCompileResult DstCompileResult; | ||||
| enum DstCompileStatus { | ||||
| @@ -38,7 +37,7 @@ enum DstCompileStatus { | ||||
|     DST_COMPILE_ERROR | ||||
| }; | ||||
| struct DstCompileResult { | ||||
|     DstCompileStatus status; | ||||
|     enum DstCompileStatus status; | ||||
|     DstFuncDef *funcdef; | ||||
|     const uint8_t *error; | ||||
|     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); | ||||
|  | ||||
| /* Parse structs */ | ||||
| typedef enum { | ||||
| enum DstContextErrorType { | ||||
|     DST_CONTEXT_ERROR_PARSE, | ||||
|     DST_CONTEXT_ERROR_COMPILE, | ||||
|     DST_CONTEXT_ERROR_RUNTIME | ||||
| } DstContextErrorType; | ||||
| }; | ||||
|  | ||||
| /* Evaluation context. Encapsulates parsing and compiling for easier integration | ||||
|  * with client programs. */ | ||||
| @@ -71,8 +70,8 @@ struct DstContext { | ||||
|     void *user; | ||||
|     int32_t index; | ||||
|  | ||||
|     int (*read_chunk)(DstContext *self, DstParserStatus status); | ||||
|     void (*on_error)(DstContext *self, DstContextErrorType type, Dst err, size_t start, size_t end); | ||||
|     int (*read_chunk)(DstContext *self, enum DstParserStatus status); | ||||
|     void (*on_error)(DstContext *self, enum DstContextErrorType type, Dst err, size_t start, size_t end); | ||||
|     void (*on_value)(DstContext *self, Dst value); | ||||
|     void (*deinit)(DstContext *self); | ||||
| }; | ||||
|   | ||||
| @@ -28,7 +28,6 @@ extern "C" { | ||||
| #endif | ||||
|  | ||||
| /* Bytecode op argument types */ | ||||
| typedef enum DstOpArgType DstOpArgType; | ||||
| enum DstOpArgType { | ||||
|     DST_OAT_SLOT, | ||||
|     DST_OAT_ENVIRONMENT, | ||||
| @@ -41,7 +40,6 @@ enum DstOpArgType { | ||||
| }; | ||||
|  | ||||
| /* Various types of instructions */ | ||||
| typedef enum DstInstructionType DstInstructionType; | ||||
| enum DstInstructionType { | ||||
|     DIT_0, /* No args */ | ||||
|     DIT_S, /* Slot(3) */ | ||||
| @@ -59,7 +57,6 @@ enum DstInstructionType { | ||||
|     DIT_SC /* Slot(1), Constant(2) */ | ||||
| }; | ||||
|  | ||||
| typedef enum DstOpCode DstOpCode; | ||||
| enum DstOpCode { | ||||
|     DOP_NOOP, | ||||
|     DOP_ERROR, | ||||
| @@ -125,7 +122,7 @@ enum DstOpCode { | ||||
| }; | ||||
|  | ||||
| /* Info about all instructions */ | ||||
| extern DstInstructionType dst_instructions[DOP_INSTRUCTION_COUNT]; | ||||
| extern enum DstInstructionType dst_instructions[DOP_INSTRUCTION_COUNT]; | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
|   | ||||
| @@ -29,7 +29,6 @@ extern "C" { | ||||
|  | ||||
| #include "dsttypes.h" | ||||
|  | ||||
| typedef enum DstParserStatus DstParserStatus; | ||||
| typedef struct DstParseState DstParseState; | ||||
| typedef struct DstParser DstParser; | ||||
|  | ||||
| @@ -60,7 +59,7 @@ struct DstParser { | ||||
| void dst_parser_init(DstParser *parser, int flags); | ||||
| void dst_parser_deinit(DstParser *parser); | ||||
| 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); | ||||
| const char *dst_parser_error(DstParser *parser); | ||||
| int dst_parse_cfun(DstArgs args); | ||||
|   | ||||
| @@ -33,9 +33,10 @@ static const void *dst_strbinsearch( | ||||
|         const uint8_t *key) { | ||||
|     size_t low = 0; | ||||
|     size_t hi = tabcount; | ||||
|     const char *t = (const char *)tab; | ||||
|     while (low < hi) { | ||||
|         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; | ||||
|         int comp = dst_cstrcmp(key, name); | ||||
|         if (comp < 0) { | ||||
|   | ||||
| @@ -79,7 +79,7 @@ int main(int argc, char **argv) { | ||||
|                 } else { | ||||
|                     flags |= DST_CLIENT_UNKNOWN; | ||||
|                 } | ||||
|             } else { | ||||
|             } else if (*arg) { | ||||
|                 /* Flag */ | ||||
|                 const char *c = arg; | ||||
|                 while (*(++c)) { | ||||
| @@ -139,9 +139,10 @@ int main(int argc, char **argv) { | ||||
|             fileRead = 1; | ||||
|             if (dst_context_file(&ctxt, env, arg)) { | ||||
|                 printf("file %s not found\n", arg); | ||||
|                 status |= 2; | ||||
|                 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; | ||||
| } | ||||
|  | ||||
| DstParserStatus dst_parser_status(DstParser *parser) { | ||||
| enum DstParserStatus dst_parser_status(DstParser *parser) { | ||||
|     if (parser->error) return DST_PARSE_ERROR; | ||||
|     if (dst_v_count(parser->states) > 1) return DST_PARSE_PENDING; | ||||
|     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) { | ||||
|     DstParserStatus status = dst_parser_status(parser); | ||||
|     enum DstParserStatus status = dst_parser_status(parser); | ||||
|     if (status == DST_PARSE_ERROR) { | ||||
|         const char *e = parser->error; | ||||
|         dst_v_empty(parser->argstack); | ||||
| @@ -487,7 +487,7 @@ const char *dst_parser_error(DstParser *parser) { | ||||
| Dst dst_parser_produce(DstParser *parser) { | ||||
|     Dst ret; | ||||
|     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(); | ||||
|     ret = parser->argstack[0]; | ||||
|     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 | ||||
| # IN THE SOFTWARE. | ||||
|  | ||||
| (print "\nRunning basic tests...\n") | ||||
| (print "\nRunning Suite 0 tests...\n") | ||||
|  | ||||
| (var num-tests-passed 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")) | ||||
		Reference in New Issue
	
	Block a user
	 bakpakin
					bakpakin