mirror of
https://github.com/janet-lang/janet
synced 2024-12-23 23:10:26 +00:00
Work on emscripten support. Works with sync code.
This commit is contained in:
parent
61645c82b1
commit
2b1dd79f55
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,6 +4,7 @@ dst
|
|||||||
/build
|
/build
|
||||||
/Release
|
/Release
|
||||||
/Debug
|
/Debug
|
||||||
|
/Emscripten
|
||||||
|
|
||||||
# Generated files
|
# Generated files
|
||||||
*.gen.h
|
*.gen.h
|
||||||
|
@ -29,25 +29,6 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
|||||||
include_directories(src/include)
|
include_directories(src/include)
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
# Make tools for generating embeddable headers
|
|
||||||
add_executable(xxd src/tools/xxd.c)
|
|
||||||
|
|
||||||
# Generate header containing standard library
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT dststlbootstrap.h
|
|
||||||
COMMAND xxd ${CMAKE_CURRENT_SOURCE_DIR}/src/compiler/boot.dst dststlbootstrap.h dst_stl_bootstrap_gen
|
|
||||||
DEPENDS xxd src/compiler/boot.dst
|
|
||||||
COMMENT "Generating stl bootstrap C header for embedding"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Generate header containing main client script
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT clientinit.h
|
|
||||||
COMMAND xxd ${CMAKE_CURRENT_SOURCE_DIR}/src/mainclient/init.dst clientinit.h dst_mainclient_init
|
|
||||||
DEPENDS xxd src/mainclient/init.dst
|
|
||||||
COMMENT "Generating mainclient init C header for embedding"
|
|
||||||
)
|
|
||||||
|
|
||||||
set(ASSEMBLER_SOURCES
|
set(ASSEMBLER_SOURCES
|
||||||
src/assembler/asm.c
|
src/assembler/asm.c
|
||||||
)
|
)
|
||||||
@ -128,11 +109,27 @@ src/include/dst/dsttypes.h
|
|||||||
|
|
||||||
# Build the executable
|
# Build the executable
|
||||||
add_executable(${TARGET_NAME} ${REPL_SOURCES})
|
add_executable(${TARGET_NAME} ${REPL_SOURCES})
|
||||||
if (UNIX)
|
if (UNIX AND NOT EMSCRIPTEN)
|
||||||
target_link_libraries(${TARGET_NAME} m dl)
|
target_link_libraries(${TARGET_NAME} m dl)
|
||||||
endif (UNIX)
|
endif (UNIX AND NOT EMSCRIPTEN)
|
||||||
set_target_properties(${TARGET_NAME} PROPERTIES PUBLIC_HEADER "${DST_PUBLIC_HEADERS}")
|
set_target_properties(${TARGET_NAME} PROPERTIES PUBLIC_HEADER "${DST_PUBLIC_HEADERS}")
|
||||||
|
|
||||||
|
# Generate header containing standard library
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT dststlbootstrap.h
|
||||||
|
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/dststlbootstrap.cmake
|
||||||
|
DEPENDS src/compiler/boot.dst
|
||||||
|
COMMENT "Generating stl bootstrap C header for embedding"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Generate header containing main client script
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT clientinit.h
|
||||||
|
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/dstmainclientinit.cmake
|
||||||
|
DEPENDS src/mainclient/init.dst
|
||||||
|
COMMENT "Generating mainclient init C header for embedding"
|
||||||
|
)
|
||||||
|
|
||||||
# Install
|
# Install
|
||||||
install(TARGETS ${TARGET_NAME}
|
install(TARGETS ${TARGET_NAME}
|
||||||
LIBRARY DESTINATION "lib"
|
LIBRARY DESTINATION "lib"
|
||||||
@ -140,6 +137,15 @@ install(TARGETS ${TARGET_NAME}
|
|||||||
PUBLIC_HEADER DESTINATION "include/dst"
|
PUBLIC_HEADER DESTINATION "include/dst"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Emscripten specifics
|
||||||
|
if (DEFINED EMSCRIPTEN)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s ABORTING_MALLOC=0")
|
||||||
|
# set_target_properties(${TARGET_NAME} PROPERTIES SUFFIX ".html")
|
||||||
|
# Copy index.html to build folder.
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/web/index.html
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/index.html COPYONLY)
|
||||||
|
endif (DEFINED EMSCRIPTEN)
|
||||||
|
|
||||||
# Add some test scripts
|
# Add some test scripts
|
||||||
enable_testing()
|
enable_testing()
|
||||||
add_test(suite0 ${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/test/suite0.dst)
|
add_test(suite0 ${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/test/suite0.dst)
|
||||||
|
83
cmake/bin2h.cmake
Normal file
83
cmake/bin2h.cmake
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
# From https://gist.github.com/sivachandran/3a0de157dccef822a230
|
||||||
|
|
||||||
|
include(CMakeParseArguments)
|
||||||
|
|
||||||
|
# Function to wrap a given string into multiple lines at the given column position.
|
||||||
|
# Parameters:
|
||||||
|
# VARIABLE - The name of the CMake variable holding the string.
|
||||||
|
# AT_COLUMN - The column position at which string will be wrapped.
|
||||||
|
function(WRAP_STRING)
|
||||||
|
set(oneValueArgs VARIABLE AT_COLUMN)
|
||||||
|
cmake_parse_arguments(WRAP_STRING "${options}" "${oneValueArgs}" "" ${ARGN})
|
||||||
|
|
||||||
|
string(LENGTH ${${WRAP_STRING_VARIABLE}} stringLength)
|
||||||
|
math(EXPR offset "0")
|
||||||
|
|
||||||
|
while(stringLength GREATER 0)
|
||||||
|
|
||||||
|
if(stringLength GREATER ${WRAP_STRING_AT_COLUMN})
|
||||||
|
math(EXPR length "${WRAP_STRING_AT_COLUMN}")
|
||||||
|
else()
|
||||||
|
math(EXPR length "${stringLength}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
string(SUBSTRING ${${WRAP_STRING_VARIABLE}} ${offset} ${length} line)
|
||||||
|
set(lines "${lines}\n${line}")
|
||||||
|
|
||||||
|
math(EXPR stringLength "${stringLength} - ${length}")
|
||||||
|
math(EXPR offset "${offset} + ${length}")
|
||||||
|
endwhile()
|
||||||
|
|
||||||
|
set(${WRAP_STRING_VARIABLE} "${lines}" PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Function to embed contents of a file as byte array in C/C++ header file(.h). The header file
|
||||||
|
# will contain a byte array and integer variable holding the size of the array.
|
||||||
|
# Parameters
|
||||||
|
# SOURCE_FILE - The path of source file whose contents will be embedded in the header file.
|
||||||
|
# VARIABLE_NAME - The name of the variable for the byte array. The string "_SIZE" will be append
|
||||||
|
# to this name and will be used a variable name for size variable.
|
||||||
|
# HEADER_FILE - The path of header file.
|
||||||
|
# APPEND - If specified appends to the header file instead of overwriting it
|
||||||
|
# NULL_TERMINATE - If specified a null byte(zero) will be append to the byte array. This will be
|
||||||
|
# useful if the source file is a text file and we want to use the file contents
|
||||||
|
# as string. But the size variable holds size of the byte array without this
|
||||||
|
# null byte.
|
||||||
|
# Usage:
|
||||||
|
# bin2h(SOURCE_FILE "Logo.png" HEADER_FILE "Logo.h" VARIABLE_NAME "LOGO_PNG")
|
||||||
|
function(BIN2H)
|
||||||
|
set(options APPEND NULL_TERMINATE)
|
||||||
|
set(oneValueArgs SOURCE_FILE VARIABLE_NAME HEADER_FILE)
|
||||||
|
cmake_parse_arguments(BIN2H "${options}" "${oneValueArgs}" "" ${ARGN})
|
||||||
|
|
||||||
|
# reads source file contents as hex string
|
||||||
|
file(READ ${BIN2H_SOURCE_FILE} hexString HEX)
|
||||||
|
string(LENGTH ${hexString} hexStringLength)
|
||||||
|
|
||||||
|
# appends null byte if asked
|
||||||
|
if(BIN2H_NULL_TERMINATE)
|
||||||
|
set(hexString "${hexString}00")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# wraps the hex string into multiple lines at column 32(i.e. 16 bytes per line)
|
||||||
|
wrap_string(VARIABLE hexString AT_COLUMN 32)
|
||||||
|
math(EXPR arraySize "${hexStringLength} / 2")
|
||||||
|
|
||||||
|
# adds '0x' prefix and comma suffix before and after every byte respectively
|
||||||
|
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1, " arrayValues ${hexString})
|
||||||
|
# removes trailing comma
|
||||||
|
string(REGEX REPLACE ", $" "" arrayValues ${arrayValues})
|
||||||
|
|
||||||
|
# converts the variable name into proper C identifier
|
||||||
|
string(MAKE_C_IDENTIFIER "${BIN2H_VARIABLE_NAME}" BIN2H_VARIABLE_NAME)
|
||||||
|
|
||||||
|
# declares byte array
|
||||||
|
set(arrayDefinition "const unsigned char ${BIN2H_VARIABLE_NAME}[] = { ${arrayValues} };")
|
||||||
|
|
||||||
|
set(declarations "${arrayDefinition}\n\n${arraySizeDefinition}\n\n")
|
||||||
|
if(BIN2H_APPEND)
|
||||||
|
file(APPEND ${BIN2H_HEADER_FILE} "${declarations}")
|
||||||
|
else()
|
||||||
|
file(WRITE ${BIN2H_HEADER_FILE} "${declarations}")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
9
cmake/dstmainclientinit.cmake
Normal file
9
cmake/dstmainclientinit.cmake
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Include bin2h cmake codeo
|
||||||
|
set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
|
||||||
|
include(bin2h)
|
||||||
|
|
||||||
|
bin2h (
|
||||||
|
SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../src/mainclient/init.dst
|
||||||
|
HEADER_FILE "clientinit.h"
|
||||||
|
VARIABLE_NAME "dst_mainclient_init"
|
||||||
|
)
|
9
cmake/dststlbootstrap.cmake
Normal file
9
cmake/dststlbootstrap.cmake
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Include bin2h cmake codeo
|
||||||
|
set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
|
||||||
|
include(bin2h)
|
||||||
|
|
||||||
|
bin2h (
|
||||||
|
SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../src/compiler/boot.dst
|
||||||
|
HEADER_FILE "dststlbootstrap.h"
|
||||||
|
VARIABLE_NAME dst_stl_bootstrap_gen
|
||||||
|
)
|
@ -145,6 +145,8 @@ If no match is found, returns nil"
|
|||||||
|
|
||||||
(defn even? [x] (== 0 (% x 2)))
|
(defn even? [x] (== 0 (% x 2)))
|
||||||
(defn odd? [x] (== 1 (% x 2)))
|
(defn odd? [x] (== 1 (% x 2)))
|
||||||
|
(defn inc [x] (+ x 1))
|
||||||
|
(defn dec [x] (- x 1))
|
||||||
|
|
||||||
(defmacro let [bindings & body]
|
(defmacro let [bindings & body]
|
||||||
(def head (ast-unwrap1 bindings))
|
(def head (ast-unwrap1 bindings))
|
||||||
@ -247,6 +249,7 @@ onvalue."
|
|||||||
(do
|
(do
|
||||||
(defn val-stream [chunks onerr]
|
(defn val-stream [chunks onerr]
|
||||||
(var going true)
|
(var going true)
|
||||||
|
# Stream of characters
|
||||||
(def chars (fiber (fn []
|
(def chars (fiber (fn []
|
||||||
(def buf @"")
|
(def buf @"")
|
||||||
(var len 1)
|
(var len 1)
|
||||||
@ -259,6 +262,7 @@ onvalue."
|
|||||||
0)))
|
0)))
|
||||||
(var temp nil)
|
(var temp nil)
|
||||||
(var tempval nil)
|
(var tempval nil)
|
||||||
|
# Stream of values
|
||||||
(def f (fiber (fn []
|
(def f (fiber (fn []
|
||||||
(def p (parser 1))
|
(def p (parser 1))
|
||||||
(while going
|
(while going
|
||||||
@ -328,6 +332,7 @@ onvalue."
|
|||||||
(def newenv (make-env))
|
(def newenv (make-env))
|
||||||
(defn chunks [buf]
|
(defn chunks [buf]
|
||||||
(file-write stdout ">> ")
|
(file-write stdout ">> ")
|
||||||
|
(file-flush stdout)
|
||||||
(file-read stdin :line buf))
|
(file-read stdin :line buf))
|
||||||
(defn onvalue [x]
|
(defn onvalue [x]
|
||||||
(put newenv '_ @{'value x})
|
(put newenv '_ @{'value x})
|
||||||
|
@ -31,6 +31,13 @@ typedef HINSTANCE Clib;
|
|||||||
#define load_clib(name) LoadLibrary((name))
|
#define load_clib(name) LoadLibrary((name))
|
||||||
#define symbol_clib(lib, sym) GetProcAddress((lib), (sym))
|
#define symbol_clib(lib, sym) GetProcAddress((lib), (sym))
|
||||||
#define error_clib() "could not load dynamic library"
|
#define error_clib() "could not load dynamic library"
|
||||||
|
#elif defined(DST_WEB)
|
||||||
|
#include <emscripten.h>
|
||||||
|
/* TODO - figure out how loading modules will work in JS */
|
||||||
|
typedef int Clib;
|
||||||
|
#define load_clib(name) 0
|
||||||
|
#define symbol_clib(lib, sym) 0
|
||||||
|
#define error_clib() "could not load dynamic library"
|
||||||
#else
|
#else
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
typedef void *Clib;
|
typedef void *Clib;
|
||||||
|
@ -53,7 +53,9 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Check Windows */
|
/* Check Windows */
|
||||||
#if defined(WIN32) || defined(_WIN32)
|
#ifdef __EMSCRIPTEN__
|
||||||
|
#define DST_WEB 1
|
||||||
|
#elif defined(WIN32) || defined(_WIN32)
|
||||||
#define DST_WINDOWS 1
|
#define DST_WINDOWS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
(when (or should-repl no-file)
|
(when (or should-repl no-file)
|
||||||
(print (string "Dst " VERSION " Copyright (C) 2017-2018 Calvin Rose"))
|
(print (string "Dst " VERSION " Copyright (C) 2017-2018 Calvin Rose"))
|
||||||
(repl))
|
(repl)
|
||||||
|
(print "bye!"))
|
||||||
|
|
||||||
)
|
)
|
||||||
|
141
web/index.html
Normal file
141
web/index.html
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<title>Dst</title>
|
||||||
|
<style type="text/css" media="screen">
|
||||||
|
/* http://meyerweb.com/eric/tools/css/reset/
|
||||||
|
v2.0 | 20110126
|
||||||
|
License: none (public domain)
|
||||||
|
*/
|
||||||
|
|
||||||
|
html, body, div, span, applet, object, iframe,
|
||||||
|
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||||
|
a, abbr, acronym, address, big, cite, code,
|
||||||
|
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||||
|
small, strike, strong, sub, sup, tt, var,
|
||||||
|
b, u, i, center,
|
||||||
|
dl, dt, dd, ol, ul, li,
|
||||||
|
fieldset, form, label, legend,
|
||||||
|
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||||
|
article, aside, canvas, details, embed,
|
||||||
|
figure, figcaption, footer, header, hgroup,
|
||||||
|
menu, nav, output, ruby, section, summary,
|
||||||
|
time, mark, audio, video {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
font-size: 100%;
|
||||||
|
font: inherit;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
/* HTML5 display-role reset for older browsers */
|
||||||
|
article, aside, details, figcaption, figure,
|
||||||
|
footer, header, hgroup, menu, nav, section {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
ol, ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
blockquote, q {
|
||||||
|
quotes: none;
|
||||||
|
}
|
||||||
|
blockquote:before, blockquote:after,
|
||||||
|
q:before, q:after {
|
||||||
|
content: '';
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#prompt {
|
||||||
|
white-space: nowrap;
|
||||||
|
width: calc(100% - 14px);
|
||||||
|
overflow: hidden;
|
||||||
|
font-family: monospace;
|
||||||
|
border: solid 2px black;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
#prompt br {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
#prompt * {
|
||||||
|
display:inline;
|
||||||
|
white-space:nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#console {
|
||||||
|
border: solid 2px black;
|
||||||
|
width: calc(100% - 4px);
|
||||||
|
min-height: 200px;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre id="console"></pre>
|
||||||
|
<div contenteditable="true" id="prompt"></div>
|
||||||
|
<script>
|
||||||
|
var con = document.getElementById('console');
|
||||||
|
var Module = {
|
||||||
|
|
||||||
|
preRun: function() {
|
||||||
|
var input = "";
|
||||||
|
var i = 0;
|
||||||
|
function stdin() {
|
||||||
|
if (input === "") {
|
||||||
|
input = prompt('Input:');
|
||||||
|
}
|
||||||
|
if (i < input.length) {
|
||||||
|
var code = input.charCodeAt(i);
|
||||||
|
++i;
|
||||||
|
return code;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendChunk(chunk) {
|
||||||
|
con.innerText += chunk + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
var outbuf = "";
|
||||||
|
function stdout(asciiCode) {
|
||||||
|
if (asciiCode === 10) {
|
||||||
|
appendChunk(outbuf);
|
||||||
|
outbuf = '';
|
||||||
|
} else if (asciiCode === null) {
|
||||||
|
appendChunk(outbuf);
|
||||||
|
outbuf = ' ... ';
|
||||||
|
} else {
|
||||||
|
outbuf += String.fromCharCode(asciiCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var errbuf = "";
|
||||||
|
function stderr(asciiCode) {
|
||||||
|
if (asciiCode == 10) {
|
||||||
|
appendChunk(errbuf);
|
||||||
|
errbuf = '';
|
||||||
|
} else if (asciiCode === null) {
|
||||||
|
appendChunk(errbuf);
|
||||||
|
errbuf = ' ... ';
|
||||||
|
} else {
|
||||||
|
errbuf += String.fromCharCode(asciiCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FS.init(stdin, stdout, stderr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script src="dst.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user