1.Nim
我喜欢用Nim编码,是因为它很有意思。Nim模糊了编译和脚本语言之间的界线。下面是源代码:
proc update(options: Options) =
## Downloads the package list from the specified URL.
##
## If the download is successful, the global didUpdatePackages is set to
## true. Otherwise an exception is raised on error.
let url =
if options.action.typ == actionUpdate and options.action.optionalURL != "":
options.action.optionalURL
else:
defaultPackageURL
echo("Downloading package list from " & url)
downloadFile(url, options.getNimbleDir() / "packages.json")
echo("Done.")
还有长一点的:
proc parseConfig*(): Config =
result = initConfig()
var confFile = getConfigDir() / "nimble" / "nimble.ini"
var f = newFileStream(confFile, fmRead)
if f == nil:
# Try the old deprecated babel.ini
confFile = getConfigDir() / "babel" / "babel.ini"
f = newFileStream(confFile, fmRead)
if f != nil:
echo("[Warning] Using deprecated config file at ", confFile)
if f != nil:
echo("Reading from config file at ", confFile)
var p: CfgParser
open(p, f, confFile)
while true:
var e = next(p)
case e.kind
of cfgEof:
break
of cfgSectionStart: discard
of cfgKeyValuePair, cfgOption:
case e.key.normalize
of "nimbledir":
# Ensure we don't restore the deprecated nimble dir.
if e.value != getHomeDir() / ".babel":
result.nimbleDir = e.value
of "chcp":
result.chcp = parseBool(e.value)
else:
raise newException(NimbleError, "Unable to parse config file:" &
" Unknown key: " & e.key)
of cfgError:
raise newException(NimbleError, "Unable to parse config file: " & e.msg)
close(p)
2.Felix
Felix是独一无二的。它是C ++、ML以及许多独特构想的结合。下面摘自我写的一个小型JSON解析器:
class JSON {
typedef LineType = int;
union Value =
| Object of strdict[Value]
| Array of list[Value]
| String of string
| Number of double
| True
| False
| Null
| Error of string * LineType
;
union Token =
| TString of string
| TNumber of double
| TLBrace // {
| TRBrace // }
| TLBrak // [
| TRBrak // ]
| TColon // :
| TTrue // true
| TFalse // false
| TNull // null
| TEOF
| TError of string * LineType
;
instance Str[Token] {
fun str(t: Token) => match t with
| TString ?s => "TString \"" + s + "\""
| TNumber ?n => "TNumber " + n.str
| TLBrace => "TLBrace"
| TRBrace => "TRBrace"
| TLBrak => "TLBrak"
| TRBrak => "TRBrak"
| TColon => "TColon"
| TTrue => "TTrue"
| TFalse => "TFalse"
| TNull => "TNull"
| TEOF => "TEOF"
| TError (?s, ?i) => "error at line " + i.str + ": " + s
endmatch;
}
proc lex(s: string, line: &LineType, outs: oschannel[Token]) = {
line <- 1;
proc tok(t: Token) => write $ outs, t;
proc err(s: string) = {
tok $ TError(s, *line);
return from lex;
};
var i = 0.size;
while i < s.len do
while s.[i].isspace do
if s.[i] == "\n" do *line++; done;
i++;
if i >= s.len goto eof;
done;
// number
if s.[i].isnumeric or (i+1 < s.len and s.[i] == "-" and
s.[i+1].isnumeric) do
d := s.[i to].double;
i += d.str.len;
tok $ TNumber d;
// string
elif s.[i] == "\"" do
i++;
var st = "";
while i < s.len and s.[i] != "\n" and s.[i] != "\"" do
st += s.[i];
i++;
done;
if s.[i] != "\"" call err "unterminated string literal";
i++;
tok $ TString st;
// literals
elif s.[i to i+4] == "true" do
tok $ TTrue;
i += 4.size;
elif s.[i to i+5] == "false" do
tok $ TFalse;
i += 5.size;
elif s.[i to i+4] == "null" do
tok $ TNull;
i += 4.size;