all repos — min @ bbdaad6412ba3d40df14f5d50cc02fc41b7d6cd7

A small but practical concatenative programming language.

Implemented compiler (single files)
h3rald h3rald@h3rald.com
Wed, 09 Dec 2020 20:33:11 +0100
commit

bbdaad6412ba3d40df14f5d50cc02fc41b7d6cd7

parent

13c5981388d02fcdfa252fda617720cac168e564

6 files changed, 53 insertions(+), 17 deletions(-)

jump to
M core/env.nimcore/env.nim

@@ -6,11 +6,13 @@ HOME = getenv("USERPROFILE")

if not defined(windows): HOME = getenv("HOME") -var MINRC* {.threadvar.} : string +var MINRC* {.threadvar.}: string MINRC = HOME / ".minrc" -var MINSYMBOLS* {.threadvar.} : string +var MINSYMBOLS* {.threadvar.}: string MINSYMBOLS = HOME / ".min_symbols" -var MINHISTORY* {.threadvar.} : string +var MINHISTORY* {.threadvar.}: string MINHISTORY = HOME / ".min_history" var MINLIBS* {.threadvar.} : string -MINLIBS = HOME / ".minlibs"+MINLIBS = HOME / ".minlibs" +var MINCOMPILED* {.threadvar.}: bool +MINCOMPILED = false
M core/interpreter.nimcore/interpreter.nim

@@ -282,7 +282,9 @@

proc compile*(i: In): seq[string] {.discardable, extern:"min_exported_symbol_$1".} = result = newSeq[string](0) result.add "import min" + result.add "MINCOMPILED = true" result.add "var i = newMinInterpreter(\"$#\")" % i.filename + result.add "i.stdLib()" while i.parser.token != tkEof: if i.trace.len == 0: i.stackcopy = i.stack
M core/parser.nimcore/parser.nim

@@ -688,12 +688,11 @@ result.add op&"MinValue(kind: minQuotation, qVal: "&qvar&")"

of tkBraceLe: result = newSeq[string](0) var val: MinValue - var scopevar = "scope" & $genOid() - var valvar = "val" & $genOid() - result.add "var "&scopevar&" = newScopeRef(nil)" - result.add "var "&valvar&": MinValue" discard getToken(p) var c = 0 + var valInitialized = false + var scopevar = "scope" & $genOid() + var valvar = "val" & $genOid() while p.token != tkBraceRi: c = c+1 var instructions = p.compileMinValue(i, false)

@@ -701,6 +700,9 @@ let v = p.parseMinValue(i)

let vs = instructions.pop result = result.concat(instructions) if val.isNil: + if not valInitialized: + result.add "var "&valvar&": MinValue" + valInitialized = true result.add valvar&" = "&vs elif v.kind == minSymbol: let key = v.symVal

@@ -714,7 +716,7 @@ raiseInvalid("Invalid dictionary key: " & $v)

eat(p, tkBraceRi) if c mod 2 != 0: raiseInvalid("Invalid dictionary") - # TODO: check + result.add "var "&scopevar&" = newScopeRef(nil)" result.add op&"MinValue(kind: minDictionary, scope: "&scopevar&")" of tkSymbol: result = @[op&"MinValue(kind: minSymbol, symVal: "&p.a.escapeJson&", column: " & $p.getColumn & ", line: " & $p.lineNumber & ", filename: "&p.filename.escapeJson&")"]
M lib/min_lang.nimlib/min_lang.nim

@@ -665,6 +665,9 @@ var q = vals[0]

q.qVal.reverse i.dequote(q) + def.symbol("compiled?") do (i: In): + i.push MINCOMPILED.newVal + # Converters def.symbol("string") do (i: In):
M min.nimmin.nim

@@ -3,7 +3,6 @@ {.passL: "-rdynamic".}

import streams, critbits, - parseopt, strutils, os, json,

@@ -16,7 +15,6 @@ import

packages/nimline/nimline, packages/niftylogger, core/env, - core/consts, core/parser, core/value, core/scope,

@@ -42,6 +40,7 @@ import lib/min_crypto

import lib/min_math export + env, parser, interpreter, utils,

@@ -52,6 +51,7 @@ min_lang

const PRELUDE* = "prelude.min".slurp.strip +var NIMOPTIONS* = "" var customPrelude = "" if logging.getHandlers().len == 0:

@@ -120,6 +120,7 @@ return toSeq(walkDir(dir, true)).filterIt(it.path.toLowerAscii.startsWith(f.toLowerAscii)).mapIt("\"$1" % [it.path.replace("\\", "/")])

return symbols proc stdLib*(i: In) = + setLogFilter(lvlNotice) if not MINSYMBOLS.fileExists: MINSYMBOLS.writeFile("{}") if not MINHISTORY.fileExists:

@@ -194,12 +195,21 @@ discard

i.close() proc compile*(i: In, s: Stream) = + if "nim".findExe == "": + error "Nim compiler not found, unable to compile." + quit(7) i.open(s, i.filename) discard i.parser.getToken() try: + MINCOMPILED = true + let nimFile = i.filename.changeFileExt("nim") + notice("Generating $#..." % nimFile) let r = i.compile() - for line in r: - echo line + writeFile(nimFile, r.join("\n")) + let cmd = "nim c $#$#" % [NIMOPTIONS&" ", nimFile] + notice("Calling Nim compiler:") + notice(cmd) + discard execShellCmd(cmd) except: discard i.close()

@@ -212,7 +222,7 @@ i.interpret(s)

else: i.compile(s) -proc minString*(buffer: string) = +proc minStr*(buffer: string) = minStream(newStringStream(buffer), "input") proc minFile*(filename: string, op = "interpret") =

@@ -306,6 +316,10 @@ i.minRepl(simple)

when isMainModule: + import + parseopt, + core/consts + var REPL = false var SIMPLEREPL = false var INSTALL = false

@@ -331,6 +345,7 @@ -i, --interactive Start $1 shell (with advanced prompt)

-j, --interactive-simple Start $1 shell (without advanced prompt) -l, --log Set log level (debug|info|notice|warn|error|fatal) Default: notice + -n, --passN Pass options to the nim compiler (if -c is set) -p, --prelude:<file.min> If specified, it loads <file.min> instead of the default prelude code -v, —-version Print the program version""" % [pkgName, pkgVersion]

@@ -354,6 +369,8 @@ of "log", "l":

if file == "": var val = val setLogLevel(val) + of "passN", "n": + NIMOPTIONS = val of "evaluate", "e": if file == "": s = val

@@ -387,7 +404,7 @@ var op = "interpret"

if COMPILE: op = "compile" if s != "": - minString(s) + minStr(s) elif file != "": minFile file, op elif INSTALL:
M run.minrun.min

@@ -3,10 +3,20 @@

;Capture a reference of default symbols before more are added symbols =min-symbols +2 :n-args +1 :taskspec-arg + +(compiled?) +( + 1 @n-args + 0 @taskspec-arg +) +when + ; Validation -(args size 2 <) ("No task specified" error 1 exit) when +(args size n-args <) ("No task specified" error 1 exit) when -args 1 get ":" split =taskspec +args taskspec-arg get ":" split =taskspec taskspec 0 get :task "default" :subtask (taskspec size 1 >) (taskspec 1 get @subtask) when