diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/vm/tasmparser.nim | 174 | ||||
-rw-r--r-- | tests/vm/tcompiletimetable.nim | 11 |
2 files changed, 179 insertions, 6 deletions
diff --git a/tests/vm/tasmparser.nim b/tests/vm/tasmparser.nim new file mode 100644 index 000000000..24ccb2ec8 --- /dev/null +++ b/tests/vm/tasmparser.nim @@ -0,0 +1,174 @@ + +# bug #1513 + +import os, parseutils, strutils, ropes, macros + +var + code {.compileTime.} = "" + start {.compileTime.} = 0 + line {.compileTime.} = 1 + cpp {.compileTime.} = "" + token {.compileTime.} = "" + +proc log (msg: string) {.compileTime.} = + echo msg + +proc asmx64 () {.compileTime} = + + #log "code = $1" % code + + const asmx64pre = "{.emit: \"\"\"{x64asm& x= *x64asm_ptr(`asm0`); try {" + const asmx64post = "} catch (Xbyak::Error e) { printf (\"asmx64 error: %s\\n\", e.what ()); }}\"\"\".} " + + const xp = "x." + + const symbolStart = { '_', 'a'..'z', 'A' .. 'Z' } + const symbol = { '0'..'9' } + symbolStart + const eolComment = { ';' } + const endOfLine = { '\l', '\r' } + const leadingWhiteSpace = { ' ' } + + const end_or_comment = endOfLine + eolComment + { '\0' } + + const passthrough_start = { '{', '`' } + const passthrough_end = { '}', '`', '\0' } + + const end_or_symbol_or_comment_or_passthrough = symbolStart + end_or_comment + passthrough_start + + + proc abortAsmParse (err:string) = + # + + let codeLen = code.len + #let codeEnd = codeLen-1 + cpp.add asmx64pre + + #log "{$1}\n" % [code] + + type asmParseState = enum leading, mnemonic, betweenArguments, arguments, endCmd, skipToEndOfLine + + var state:asmParseState = leading + + proc checkEnd (err:string) = + let ch = code [start] + if int (ch) == 0: + abortAsmParse (err) + + proc get_passthrough () = + inc start + let prev_start = start + let prev_token = token + start += code.parseUntil (token, passthrough_end, start) + checkEnd ("Failed to find passthrough end delimiter from offset $1 for:$2\n$3" % [$prev_start, $(code [prev_start-prev_token.len..prev_start]), token[1..token.len-1]]) + inc start + cpp.add "`" + cpp.add token + cpp.add "`" + + var inparse = true + + proc checkCmdEnd () = + if codeLen == start: + state = endCmd + inparse = false + + while inparse: + checkCmdEnd () + + log ("state=$1 start=$2" % [$state, $start]) + + case state: + of leading: + + echo "b100 ", start + start += code.skipWhile (leadingWhiteSpace, start) + echo "b200 ", start + let ch = code [start] + if ch in endOfLine: + inc (line) + #echo "c100 ", start, ' ', code + start += code.skipWhile (endOfline, start) + #echo "c200 ", start, ' ', code + continue + elif ch in symbolStart: + state = mnemonic + elif ch in eolComment: + state = skipToEndOfLine + elif ch in passthrough_start: + get_passthrough () + echo "d100 ", start + start += code.parseUntil (token, end_or_symbol_or_comment_or_passthrough, start) + echo "d200 ", start + cpp.add token + state = mnemonic + elif int (ch) == 0: + break + else: + abortAsmParse ("after '$3' illegal character at offset $1: $2" % [$start, $(int (ch)), token]) + + of mnemonic: + echo "e100 ", start + start += code.parseWhile (token, symbol, start) + echo "e200 ", start + cpp.add xp + cpp.add token + cpp.add "(" + state = betweenArguments + + of betweenArguments: + let tmp = start + let rcode = code + start += rcode.parseUntil (token, end_or_symbol_or_comment_or_passthrough, tmp) + cpp.add token + + if codeLen <= start: + state = endCmd + continue + + let ch = code [start] + if ch in passthrough_start: + get_passthrough () + continue + if (ch in {'x', 'X'}) and ('0' == code [start-1]): + token = $(code [start]) + cpp.add token + inc start + continue + state = arguments + + of arguments: + if code [start] in end_or_comment: + state = endCmd + continue + start += code.parseWhile (token, symbol, start) + cpp.add xp + cpp.add token + state = betweenArguments + + of endCmd: + cpp.add ");\n" + state = skipToEndOfLine + + of skipToEndOfLine: + echo "a100 ", start + start += code.skipUntil (endOfLine, start) + echo "a200 ", start + start += code.skipWhile (endOfline, start) + echo "a300 ", start + inc line + state = leading + + cpp.add asmx64post + + echo ($cpp) + +macro asmx64x (code_in:expr) : stmt = + code = $code_in + echo ("code.len = $1, code = >>>$2<<<" % [$code.len, code]) + asmx64 () + discard result + +asmx64x """ + mov rax, {m} + ret +""" diff --git a/tests/vm/tcompiletimetable.nim b/tests/vm/tcompiletimetable.nim index f1d3ecd4e..df6ead56f 100644 --- a/tests/vm/tcompiletimetable.nim +++ b/tests/vm/tcompiletimetable.nim @@ -2,18 +2,19 @@ discard """ msg: '''2 3 4:2 - ''' +Got Hi +Got Hey''' """ # bug #404 -import macros, tables +import macros, tables, strtabs var ZOOT{.compileTime.} = initTable[int, int](2) var iii {.compiletime.} = 1 macro zoo:stmt= - zoot[iii] = iii*2 + ZOOT[iii] = iii*2 inc iii echo iii @@ -29,9 +30,7 @@ tupleUnpack # bug #903 -import strtabs - -var x {.compileTime.}: PStringTable +var x {.compileTime.}: StringTableRef macro addStuff(stuff, body: expr): stmt {.immediate.} = result = newNimNode(nnkStmtList) |