From 571eb786b46d7833709f58885f76cd54cd88a7e5 Mon Sep 17 00:00:00 2001 From: vvakame Date: Thu, 23 Feb 2017 00:03:21 +0900 Subject: [PATCH] TypeScript: setup initial environment --- Makefile | 3 ++- ts/.gitignore | 5 +++++ ts/Makefile | 34 ++++++++++++++++++++++++++++++++++ ts/core.ts | 0 ts/env.ts | 0 ts/mal.ts | 0 ts/node_readline.ts | 45 +++++++++++++++++++++++++++++++++++++++++++++ ts/package.json | 19 +++++++++++++++++++ ts/printer.ts | 0 ts/reader.ts | 0 ts/run | 2 ++ ts/step0_repl.ts | 0 ts/tsconfig.json | 15 +++++++++++++++ ts/types.ts | 0 14 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 ts/.gitignore create mode 100644 ts/Makefile create mode 100644 ts/core.ts create mode 100644 ts/env.ts create mode 100644 ts/mal.ts create mode 100644 ts/node_readline.ts create mode 100644 ts/package.json create mode 100644 ts/printer.ts create mode 100644 ts/reader.ts create mode 100755 ts/run create mode 100644 ts/step0_repl.ts create mode 100644 ts/tsconfig.json create mode 100644 ts/types.ts diff --git a/Makefile b/Makefile index 1dbff814..ab2b4fd0 100644 --- a/Makefile +++ b/Makefile @@ -81,7 +81,7 @@ IMPLS = ada awk bash basic c d chuck clojure coffee common-lisp cpp crystal cs d erlang elisp elixir es6 factor forth fsharp go groovy guile haskell \ haxe io java julia js kotlin logo lua make mal ocaml matlab miniMAL \ nim objc objpascal perl perl6 php pil plpgsql plsql powershell ps \ - python r racket rpython ruby rust scala skew swift swift3 tcl vb vhdl \ + python r racket rpython ruby rust scala skew swift swift3 tcl ts vb vhdl \ vimscript EXTENSION = .mal @@ -210,6 +210,7 @@ skew_STEP_TO_PROG = skew/$($(1)).js swift_STEP_TO_PROG = swift/$($(1)) swift3_STEP_TO_PROG = swift3/$($(1)) tcl_STEP_TO_PROG = tcl/$($(1)).tcl +ts_STEP_TO_PROG = ts/$($(1)).js vb_STEP_TO_PROG = vb/$($(1)).exe vhdl_STEP_TO_PROG = vhdl/$($(1)) vimscript_STEP_TO_PROG = vimscript/$($(1)).vim diff --git a/ts/.gitignore b/ts/.gitignore new file mode 100644 index 00000000..0aa7778c --- /dev/null +++ b/ts/.gitignore @@ -0,0 +1,5 @@ +node_modules/ + +npm-debug.log + +*.js diff --git a/ts/Makefile b/ts/Makefile new file mode 100644 index 00000000..3af357f0 --- /dev/null +++ b/ts/Makefile @@ -0,0 +1,34 @@ +SOURCES_BASE = types.ts reader.ts printer.ts +SOURCES_LISP = env.ts core.ts stepA_mal.ts +SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) + +all: node_modules dist + +node_modules: + npm install + +dist: mal.js mal + +%.js: %.js + ./node_modules/.bin/tsc -p ./ + +mal.js: $(SOURCES) + ./node_modules/.bin/tsc -p ./ + +mal: mal.js + echo "#!/usr/bin/env node" > $@ + cat $< >> $@ + chmod +x $@ + +clean: + rm -f *.js mal + + +.PHONY: stats tests $(TESTS) + +stats: $(SOURCES) + @wc $^ + @printf "%5s %5s %5s %s\n" `egrep "^\w*#|^\w*$$" $^ | wc` "[comments/blanks]" +stats-lisp: $(SOURCES_LISP) + @wc $^ + @printf "%5s %5s %5s %s\n" `egrep "^\w*#|^\w*$$" $^ | wc` "[comments/blanks]" diff --git a/ts/core.ts b/ts/core.ts new file mode 100644 index 00000000..e69de29b diff --git a/ts/env.ts b/ts/env.ts new file mode 100644 index 00000000..e69de29b diff --git a/ts/mal.ts b/ts/mal.ts new file mode 100644 index 00000000..e69de29b diff --git a/ts/node_readline.ts b/ts/node_readline.ts new file mode 100644 index 00000000..2b90aa62 --- /dev/null +++ b/ts/node_readline.ts @@ -0,0 +1,45 @@ +import * as path from "path"; +import * as ffi from "ffi"; +import * as fs from "fs"; + +// IMPORTANT: choose one +const RL_LIB = "libreadline"; // NOTE: libreadline is GPL +//var RL_LIB = "libedit"; + +const HISTORY_FILE = path.join(process.env.HOME, ".mal-history"); + +const rllib = ffi.Library(RL_LIB, { + "readline": ["string", ["string"]], + "add_history": ["int", ["string"]], +}); + +let rlHistoryLoaded = false; + +export function readline(prompt?: string): string | null { + prompt = prompt || "user> "; + + if (!rlHistoryLoaded) { + rlHistoryLoaded = true; + let lines: string[] = []; + if (fs.existsSync(HISTORY_FILE)) { + lines = fs.readFileSync(HISTORY_FILE).toString().split("\n"); + } + // Max of 2000 lines + lines = lines.slice(Math.max(lines.length - 2000, 0)); + for (let i = 0; i < lines.length; i++) { + if (lines[i]) { rllib.add_history(lines[i]); } + } + } + + const line = rllib.readline(prompt); + if (line) { + rllib.add_history(line); + try { + fs.appendFileSync(HISTORY_FILE, line + "\n"); + } catch (exc) { + // ignored + } + } + + return line; +}; diff --git a/ts/package.json b/ts/package.json new file mode 100644 index 00000000..c34f9f63 --- /dev/null +++ b/ts/package.json @@ -0,0 +1,19 @@ +{ + "name": "mal", + "private": true, + "version": "1.0.0", + "description": "Make a Lisp (mal) language implemented in TypeScript", + "scripts": { + "test": "npm run test:step0", + "test:step0": "cd .. && make 'test^ts^step0'" + }, + "dependencies": { + "ffi": "^2.2.0" + }, + "devDependencies": { + "@types/ffi": "0.0.19", + "@types/node": "^7.0.5", + "typescript": "^2.1.6", + "typescript-formatter": "^4.1.1" + } +} diff --git a/ts/printer.ts b/ts/printer.ts new file mode 100644 index 00000000..e69de29b diff --git a/ts/reader.ts b/ts/reader.ts new file mode 100644 index 00000000..e69de29b diff --git a/ts/run b/ts/run new file mode 100755 index 00000000..6605303a --- /dev/null +++ b/ts/run @@ -0,0 +1,2 @@ +#!/bin/bash +exec node $(dirname $0)/${STEP:-stepA_mal}.js "${@}" diff --git a/ts/step0_repl.ts b/ts/step0_repl.ts new file mode 100644 index 00000000..e69de29b diff --git a/ts/tsconfig.json b/ts/tsconfig.json new file mode 100644 index 00000000..47439fb6 --- /dev/null +++ b/ts/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es2015", + "noImplicitAny": true, + "noEmitOnError": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "newLine": "LF", + "strictNullChecks": true, + "sourceMap": false + } +} diff --git a/ts/types.ts b/ts/types.ts new file mode 100644 index 00000000..e69de29b