slurp uses path; unidecode is improved and threadsafe
This commit is contained in:
parent
fae8ea0cee
commit
e956abbadd
9 changed files with 76 additions and 48 deletions
|
|
@ -65,7 +65,7 @@ proc popStackFrame*(c: PEvalContext) {.inline.} =
|
||||||
if (c.tos == nil): InternalError("popStackFrame")
|
if (c.tos == nil): InternalError("popStackFrame")
|
||||||
c.tos = c.tos.next
|
c.tos = c.tos.next
|
||||||
|
|
||||||
proc eval*(c: PEvalContext, n: PNode): PNode
|
proc evalMacroCall*(c: PEvalContext, n: PNode, sym: PSym): PNode
|
||||||
proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode
|
proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode
|
||||||
|
|
||||||
proc stackTraceAux(x: PStackFrame) =
|
proc stackTraceAux(x: PStackFrame) =
|
||||||
|
|
@ -835,24 +835,6 @@ proc evalTemplate(n: PNode, sym: PSym): PNode =
|
||||||
|
|
||||||
dec(evalTemplateCounter)
|
dec(evalTemplateCounter)
|
||||||
|
|
||||||
proc evalMacroCall*(c: PEvalContext, n: PNode, sym: PSym): PNode =
|
|
||||||
inc(evalTemplateCounter)
|
|
||||||
if evalTemplateCounter > 100:
|
|
||||||
GlobalError(n.info, errTemplateInstantiationTooNested)
|
|
||||||
|
|
||||||
var s = newStackFrame()
|
|
||||||
s.call = n
|
|
||||||
setlen(s.params, 2)
|
|
||||||
s.params[0] = newNodeIT(nkNilLit, n.info, sym.typ.sons[0])
|
|
||||||
s.params[1] = n
|
|
||||||
pushStackFrame(c, s)
|
|
||||||
discard eval(c, sym.ast.sons[codePos])
|
|
||||||
result = s.params[0]
|
|
||||||
popStackFrame(c)
|
|
||||||
if cyclicTree(result): GlobalError(n.info, errCyclicTree)
|
|
||||||
|
|
||||||
dec(evalTemplateCounter)
|
|
||||||
|
|
||||||
proc evalExpandToAst(c: PEvalContext, original: PNode): PNode =
|
proc evalExpandToAst(c: PEvalContext, original: PNode): PNode =
|
||||||
var
|
var
|
||||||
n = original.copyTree
|
n = original.copyTree
|
||||||
|
|
@ -1258,6 +1240,24 @@ proc evalConstExpr*(module: PSym, e: PNode): PNode =
|
||||||
if result != nil and result.kind == nkExceptBranch: result = nil
|
if result != nil and result.kind == nkExceptBranch: result = nil
|
||||||
popStackFrame(p)
|
popStackFrame(p)
|
||||||
|
|
||||||
|
proc evalMacroCall*(c: PEvalContext, n: PNode, sym: PSym): PNode =
|
||||||
|
# XXX GlobalError() is ugly here, but I don't know a better solution for now
|
||||||
|
inc(evalTemplateCounter)
|
||||||
|
if evalTemplateCounter > 100:
|
||||||
|
GlobalError(n.info, errTemplateInstantiationTooNested)
|
||||||
|
|
||||||
|
var s = newStackFrame()
|
||||||
|
s.call = n
|
||||||
|
setlen(s.params, 2)
|
||||||
|
s.params[0] = newNodeIT(nkNilLit, n.info, sym.typ.sons[0])
|
||||||
|
s.params[1] = n
|
||||||
|
pushStackFrame(c, s)
|
||||||
|
discard eval(c, sym.ast.sons[codePos])
|
||||||
|
result = s.params[0]
|
||||||
|
popStackFrame(c)
|
||||||
|
if cyclicTree(result): GlobalError(n.info, errCyclicTree)
|
||||||
|
dec(evalTemplateCounter)
|
||||||
|
|
||||||
proc myOpen(module: PSym, filename: string): PPassContext =
|
proc myOpen(module: PSym, filename: string): PPassContext =
|
||||||
var c = newEvalContext(module, filename, false)
|
var c = newEvalContext(module, filename, false)
|
||||||
pushStackFrame(c, newStackFrame())
|
pushStackFrame(c, newStackFrame())
|
||||||
|
|
|
||||||
|
|
@ -942,7 +942,7 @@ proc semSlurp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
if sonsLen(n) == 2:
|
if sonsLen(n) == 2:
|
||||||
var a = expectStringArg(c, n, 0)
|
var a = expectStringArg(c, n, 0)
|
||||||
try:
|
try:
|
||||||
var content = readFile(a.strVal)
|
var content = readFile(a.strVal.FindFile)
|
||||||
result = newStrNode(nkStrLit, content)
|
result = newStrNode(nkStrLit, content)
|
||||||
result.typ = getSysType(tyString)
|
result.typ = getSysType(tyString)
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
|
|
|
||||||
|
|
@ -1547,9 +1547,8 @@ The rules for compile-time computability are:
|
||||||
computable arguments.
|
computable arguments.
|
||||||
|
|
||||||
|
|
||||||
Constants cannot be of type ``var`` or ``object``, nor can
|
Constants cannot be of type ``ptr``, ``ref``, ``var`` or ``object``, nor can
|
||||||
they contain such a type. For the types ``ptr`` and ``ref`` only the
|
they contain such a type.
|
||||||
constant literal ``nil`` is possible.
|
|
||||||
|
|
||||||
|
|
||||||
If statement
|
If statement
|
||||||
|
|
@ -3322,7 +3321,11 @@ improve compile times.
|
||||||
A thread proc is passed to ``createThread`` and invoked indirectly; so the
|
A thread proc is passed to ``createThread`` and invoked indirectly; so the
|
||||||
``thread`` pragma implies ``procvar``.
|
``thread`` pragma implies ``procvar``.
|
||||||
|
|
||||||
If a global variable can also be marked with the ``thread`` pragma; it is
|
|
||||||
|
Threadvar pragma
|
||||||
|
----------------
|
||||||
|
|
||||||
|
A global variable can be marked with the `threadvar`:idx: pragma; it is
|
||||||
a `thead-local`:idx: variable then:
|
a `thead-local`:idx: variable then:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
|
|
|
||||||
|
|
@ -218,7 +218,7 @@ proc `$`*(t: PStringTable): string {.rtl, extern: "nstDollar".} =
|
||||||
result.add("}")
|
result.add("}")
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
const x = {"k": "v", "11": "22", "565": "67"}.newStringTable
|
var x = {"k": "v", "11": "22", "565": "67"}.newStringTable
|
||||||
assert x["k"] == "v"
|
assert x["k"] == "v"
|
||||||
assert x["11"] == "22"
|
assert x["11"] == "22"
|
||||||
assert x["565"] == "67"
|
assert x["565"] == "67"
|
||||||
|
|
|
||||||
|
|
@ -972,9 +972,9 @@ proc c_sprintf(buf, frmt: CString) {.nodecl, importc: "sprintf", varargs,
|
||||||
|
|
||||||
type
|
type
|
||||||
TFloatFormat* = enum ## the different modes of floating point formating
|
TFloatFormat* = enum ## the different modes of floating point formating
|
||||||
ffDefault, ## use the shorter floating point notation
|
ffDefault, ## use the shorter floating point notation
|
||||||
ffDecimal, ## use decimal floating point notation
|
ffDecimal, ## use decimal floating point notation
|
||||||
ffScientific ## use scientific notation (using ``e`` character)
|
ffScientific ## use scientific notation (using ``e`` character)
|
||||||
|
|
||||||
proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault,
|
proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault,
|
||||||
precision = 16): string {.noSideEffect,
|
precision = 16): string {.noSideEffect,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
# (c) Copyright 2010 Andreas Rumpf
|
# (c) Copyright 2011 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -22,23 +22,32 @@
|
||||||
## strictly one-way transformation. However a human reader will probably
|
## strictly one-way transformation. However a human reader will probably
|
||||||
## still be able to guess what original string was meant from the context.
|
## still be able to guess what original string was meant from the context.
|
||||||
##
|
##
|
||||||
## This module needs the data file "unidecode.dat" to work, so it has to be
|
## This module needs the data file "unidecode.dat" to work: You can either
|
||||||
## shipped with the application!
|
## ship this file with your application and initialize this module with the
|
||||||
|
## `loadUnidecodeTable` proc or you can define the ``embedUnidecodeTable``
|
||||||
|
## symbol to embed the file as a resource into your application.
|
||||||
|
|
||||||
import unicode
|
import unicode
|
||||||
|
|
||||||
proc loadTranslationTable(filename: string): seq[string] =
|
when defined(embedUnidecodeTable):
|
||||||
newSeq(result, 0xffff)
|
import strutils
|
||||||
var i = 0
|
|
||||||
for line in lines(filename):
|
|
||||||
result[i] = line
|
|
||||||
inc(i)
|
|
||||||
|
|
||||||
var
|
const translationTable = splitLines(slurp"unidecode/unidecode.dat")
|
||||||
translationTable: seq[string]
|
else:
|
||||||
|
# shared is fine for threading:
|
||||||
|
var translationTable: seq[string]
|
||||||
|
|
||||||
var
|
proc loadUnidecodeTable*(datafile = "unidecode.dat") =
|
||||||
datafile* = "unidecode.dat" ## location can be overwritten for deployment
|
## loads the datafile that `unidecode` to work. Unless this module is
|
||||||
|
## compiled with the ``embedUnidecodeTable`` symbol defined, this needs
|
||||||
|
## to be called by the main thread before any thread can make a call
|
||||||
|
## to `unidecode`.
|
||||||
|
when not defined(embedUnidecodeTable):
|
||||||
|
newSeq(translationTable, 0xffff)
|
||||||
|
var i = 0
|
||||||
|
for line in lines(datafile):
|
||||||
|
translationTable[i] = line
|
||||||
|
inc(i)
|
||||||
|
|
||||||
proc unidecode*(s: string): string =
|
proc unidecode*(s: string): string =
|
||||||
## Finds the sequence of ASCII characters that is the closest approximation
|
## Finds the sequence of ASCII characters that is the closest approximation
|
||||||
|
|
@ -51,15 +60,14 @@ proc unidecode*(s: string): string =
|
||||||
##
|
##
|
||||||
## Results in: "Bei Jing"
|
## Results in: "Bei Jing"
|
||||||
##
|
##
|
||||||
|
assert(not isNil(translationTable))
|
||||||
result = ""
|
result = ""
|
||||||
for r in runes(s):
|
for r in runes(s):
|
||||||
var c = int(r)
|
var c = int(r)
|
||||||
if c <=% 127: add(result, chr(c))
|
if c <=% 127: add(result, chr(c))
|
||||||
elif c <=% 0xffff:
|
elif c <% translationTable.len: add(result, translationTable[c-128])
|
||||||
if isNil(translationTable):
|
|
||||||
translationTable = loadTranslationTable(datafile)
|
|
||||||
add(result, translationTable[c-128])
|
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
|
loadUnidecodeTable("lib/pure/unidecode/unidecode.dat")
|
||||||
echo unidecode("Äußerst")
|
echo unidecode("Äußerst")
|
||||||
|
|
||||||
|
|
|
||||||
9
tests/accept/run/tunidecode.nim
Normal file
9
tests/accept/run/tunidecode.nim
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
discard """
|
||||||
|
cmd: "nimrod cc --hints:on -d:embedUnidecodeTable $# $#"
|
||||||
|
output: "Ausserst"
|
||||||
|
"""
|
||||||
|
|
||||||
|
import unidecode
|
||||||
|
|
||||||
|
unidecode("Äußerst")
|
||||||
|
|
||||||
7
todo.txt
7
todo.txt
|
|
@ -1,12 +1,15 @@
|
||||||
Version 0.8.14
|
Version 0.8.14
|
||||||
==============
|
==============
|
||||||
|
|
||||||
- fix the 'const' issues
|
- optimize unused constants away
|
||||||
- 'let x = y'; const ptr/ref
|
- 'let x = y'; const ptr/ref
|
||||||
- fix actors.nim
|
- fix actors.nim
|
||||||
- make threadvar efficient again on linux after testing
|
- make threadvar efficient again on linux after testing
|
||||||
- test the sort implementation again
|
- test the sort implementation again
|
||||||
- optional indentation for 'case' statement
|
- optional indentation for 'case' statement
|
||||||
|
- ``bind`` as a declaration
|
||||||
|
- document splicing
|
||||||
|
- fix unidecode.nim
|
||||||
|
|
||||||
|
|
||||||
version 0.9.0
|
version 0.9.0
|
||||||
|
|
@ -20,6 +23,7 @@ version 0.9.0
|
||||||
- implement closures; implement proper coroutines
|
- implement closures; implement proper coroutines
|
||||||
- make exceptions compatible with C++ exceptions
|
- make exceptions compatible with C++ exceptions
|
||||||
- ``=`` should be overloadable; requires specialization for ``=``
|
- ``=`` should be overloadable; requires specialization for ``=``
|
||||||
|
- 'const' objects including case objects
|
||||||
|
|
||||||
Bugs
|
Bugs
|
||||||
----
|
----
|
||||||
|
|
@ -93,6 +97,7 @@ Low priority
|
||||||
------------
|
------------
|
||||||
|
|
||||||
- ``with proc `+`(x, y: T): T`` for generic code
|
- ``with proc `+`(x, y: T): T`` for generic code
|
||||||
|
- new feature: ``distinct T with operations``
|
||||||
- find a way for easy constructors and destructors; (destructors are much more
|
- find a way for easy constructors and destructors; (destructors are much more
|
||||||
important than constructors)
|
important than constructors)
|
||||||
- code generated for type information is wasteful
|
- code generated for type information is wasteful
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ Changes affecting backwards compatibility
|
||||||
- The ``is`` operator is now used to check type equivalence in generic code.
|
- The ``is`` operator is now used to check type equivalence in generic code.
|
||||||
- The ``pure`` pragma for procs has been renamed to ``noStackFrame``.
|
- The ``pure`` pragma for procs has been renamed to ``noStackFrame``.
|
||||||
- The threading API has been completely redesigned.
|
- The threading API has been completely redesigned.
|
||||||
|
- The interface of the ``unidecode`` module changed and it's now thread-safe.
|
||||||
|
|
||||||
|
|
||||||
Language Additions
|
Language Additions
|
||||||
|
|
@ -50,6 +51,7 @@ Language Additions
|
||||||
a compile-time error.
|
a compile-time error.
|
||||||
- There is a new ``discardable`` pragma that can be used to mark a routine
|
- There is a new ``discardable`` pragma that can be used to mark a routine
|
||||||
so that its result can be discarded implicitely.
|
so that its result can be discarded implicitely.
|
||||||
|
- Constants can now have the type ``seq``.
|
||||||
|
|
||||||
|
|
||||||
Compiler Additions
|
Compiler Additions
|
||||||
|
|
@ -74,6 +76,7 @@ Library Additions
|
||||||
- Added ``system.mainThreadId``.
|
- Added ``system.mainThreadId``.
|
||||||
- Added ``system.allocShared``, ``system.allocShared0``,
|
- Added ``system.allocShared``, ``system.allocShared0``,
|
||||||
``system.deallocShared``, ``system.reallocShared``.
|
``system.deallocShared``, ``system.reallocShared``.
|
||||||
|
- Slicing as implemented by the system module now supports *splicing*.
|
||||||
- Added explicit channels for thread communication.
|
- Added explicit channels for thread communication.
|
||||||
- Added ``matchers`` module for email address etc. matching.
|
- Added ``matchers`` module for email address etc. matching.
|
||||||
- Added ``strutils.unindent``, ``strutils.countLines``.
|
- Added ``strutils.unindent``, ``strutils.countLines``.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue