-
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature: upgrade macro evaluation strategy to use
nimscripter
(#37)
This commit upgrades the representer to use https://github.com/beef331/nimscripter. This module is a branch between Nimscript (a subset of nim that runs in the VM) and the compiled nim. It embeds an interpreter in to the executable, and doesn't require a nim compiler to be in path. The primary advantage is the the bridge is built-in, so there is no need for recompiling to create a representation for every exercise, as the representer uses nim's macros which only function in the VM. Without this, only the VM is used, but the executable has to be recompiled every time. This also greatly simplifies the testing process, as the representation creation doesn't need to happen at compile to and injecting in. Rather, it can happen at runtime with the VM bridge. This also add the use of https://github.com/docopt/docopt.nim form command line parsing. This was not possible before, because everything happened at compile time and there was no code being run. CI: https://github.com/jiro4989/setup-nim-action is used to install nim using choosenim with the desired version. Caching is utilized to not have to redownload the dependent packages again and invalidates the cache when the nimble file changes. This is the example used on the `setup-nim-action` repo `README.md` Closes #9 as not relevant Co-authored-by: Erik Schierboom <erik_schierboom@hotmail.com> Co-authored-by: ee7 <45465154+ee7@users.noreply.github.com>
- Loading branch information
1 parent
7e9f97c
commit 34ff2b0
Showing
9 changed files
with
168 additions
and
111 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
--path:"$nim" | ||
--verbosity=0 | ||
--hint[Processing]:off | ||
--styleCheck:hint | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,42 @@ | ||
import macros, os, sequtils, strutils | ||
import representer/[mapping, normalizations] | ||
import std/[json, os, strformat, strutils] | ||
import nimscripter | ||
import representer/[mapping, types] | ||
import docopt | ||
|
||
proc switchKeysValues*(map: IdentMap): OrderedTable[string, NormalizedIdent] = | ||
toSeq(map.pairs).mapIt((it[1], it[0])).toOrderedTable | ||
const doc = """ | ||
Exercism nim representation normalizer. | ||
proc createRepresentation*(fileName: string): tuple[tree: NimNode, map: IdentMap] = | ||
var map: IdentMap | ||
let code = parseStmt fileName.staticRead | ||
result = (tree: code.normalizeStmtList(map), map: map) | ||
Usage: | ||
representer --slug=<slug> --input-dir=<in-dir> [--output-dir=<out-dir>] [--print] | ||
Options: | ||
-h --help Show this help message. | ||
-v, --version Display version. | ||
-p, --print Print the results. | ||
-s <slug>, --slug=<slug> The exercise slug. | ||
-i <in-dir>, --input-dir=<in-dir> The directory of the submission and exercise files. | ||
-o <out-dir>, --output-dir=<out-dir> The directory to output to. | ||
If omitted, output will be written to stdout. | ||
""".dedent | ||
|
||
const inDir {.strdefine.} = "" | ||
const outDir {.strdefine.} = "" | ||
const slug {.strdefine.} = "" | ||
const underSlug = slug.replace('-', '_') | ||
proc getFileContents(fileName: string): string = readFile fileName | ||
|
||
func kebabToSnakeCase(s: string): string = s.replace('-', '_') | ||
|
||
proc main() = | ||
let args = docopt(doc) | ||
let intr = loadScript(NimScriptPath("src/representer/loader.nims")) | ||
let (tree, map) = intr.invoke( | ||
getTestableRepresentation, | ||
getFileContents($args["--input-dir"] / kebabToSnakeCase($args["--slug"]) & ".nim"), true, | ||
returnType = SerializedRepresentation | ||
) | ||
if args["--output-dir"]: | ||
let outDir = $args["--output-dir"] | ||
writeFile outDir / "mapping.json", $map.parseJson | ||
writeFile outDir / "representation.txt", tree | ||
if not args["--output-dir"] or args["--print"]: | ||
echo &"{tree = }\n{map.parseJson.pretty = }" | ||
|
||
when isMainModule: | ||
import json | ||
static: | ||
let (tree, map) = createRepresentation(inDir / underSlug & ".nim") | ||
let finalMapping = map.switchKeysValues | ||
echo (%*{"map": finalMapping, "tree": tree.repr}).pretty | ||
when defined(outDir): | ||
writeFile(outDir / "representation.txt", tree.repr) | ||
writeFile(outDir / "mapping.json", $(%finalMapping)) | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import std/[json, macros] | ||
import "."/[mapping, normalizations, types] | ||
|
||
proc createRepresentation(contents: string): tuple[tree: NimNode, map: IdentMap] = | ||
var map: IdentMap | ||
let code = parseStmt(contents) | ||
result = (tree: code.normalizeStmtList(map), map: map) | ||
|
||
proc getTestableRepresentation*(contents: string, switch = false): SerializedRepresentation = | ||
let (tree, map) = createRepresentation(contents) | ||
result = (repr tree, $(if switch: %map.switchKeysValues else: %map)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import std/[sugar, tables] | ||
import mapping | ||
|
||
type | ||
Representation* = tuple | ||
tree: string | ||
map: IdentMap | ||
SerializedRepresentation* = tuple | ||
tree: string | ||
map: string | ||
|
||
proc switchKeysValues*(map: IdentMap): OrderedTable[string, NormalizedIdent] = | ||
result = collect(initOrderedTable): | ||
for key, val in map.pairs: | ||
{val: key} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters