Jump to content

S-expressions: Difference between revisions

Updated D entry
(Strings like foo# wouldn't work, because /b would cut the # I really don't know why it was after the num.)
(Updated D entry)
Line 850:
 
=={{header|D}}==
<lang d>import std.stdio:, std.conv, std.algorithm, writestd.variant, writelnstd.uni;
import std.conv: text, parse;
import std.algorithm: canFind;
import std.variant: Variant;
import std.uni: isAlpha, isNumber, isWhite;
 
alias Sexp = Variant;
Line 860 ⟶ 856:
struct Symbol {
private string name;
string toString() const { return name; }
}
 
Sexp parseSexp(in string rawtxt) {
static bool isIdentChar(in char c) @safe pure /*nothrow*/ {
return c.isAlpha || "0123456789!@#-".canFind(c);
Line 869 ⟶ 865:
 
size_t pos = 0;
 
while (isWhite(raw[pos])) pos++;
Sexp _parse() {
size_tauto i = pos + 1;
scope (exit)
pos = i;
if (rawtxt[pos] == '"') {
while (rawtxt[i] != '"' && i < rawtxt.length)
i++;
i++;
return Sexp(rawtxt[pos + 1 .. i - 1]);
} else if (isNumber(rawtxt[pos]).isNumber) {
while (isNumber(rawtxt[i]).isNumber && i < rawtxt.length)
i++;
if (rawtxt[i] == '.') {
i++;
while (isNumber(rawtxt[i]).isNumber && i < rawtxt.length)
i++;
returnauto Sexp(parse!double(rawaux = txt[pos .. i]));
return aux.parse!double.Sexp;
}
returnauto Sexp(parse!ulong(rawaux = txt[pos .. i]));
return aux.parse!ulong.Sexp;
} else if (isIdentChar(raw[pos])) {
} else whileif (isIdentChar(rawtxt[ipos])) && i < raw.length){
} else if while (isIdentChar(rawtxt[posi])) {&& i < txt.length)
i++;
return Sexp(Symbol(rawtxt[pos .. i]));
} else if (rawtxt[pos] == '(') {
Sexp[] lst;
while (rawtxt[i] != ')') {
while (isWhite(rawtxt[i]).isWhite)
i++;
pos = i;
lst ~= _parse();
i = pos;
while (isWhite(rawtxt[i]).isWhite)
i++;
}
Line 909 ⟶ 907:
return Sexp(null);
}
 
return _parse();
while (txt[pos].isWhite)
write(expr)pos++;
return _parse();
}
 
void writeSexp(Sexp expr) {
if (expr.type == typeid(string)) {
write('"\"', expr, '"');
write(expr);
write("\"");
} else if (expr.type == typeid(Sexp[])) {
'('.write("(");
auto arr = expr.get!(Sexp[]);
foreach (immutable i, e; arr) {
writeSexp(e).writeSexp;
if (i + 1 < arr.length)
write("' ")'.write;
}
')'.write(")");
} else {
write(expr).write;
}
}
 
void main() {
auto testpTest = `((data "quoted data" 123 4.5)
(data (!@# (4.5) "(more" "data)")))`.parseSexp;
auto pTest = parseSexp(test);
writeln("Parsed: ", pTest);
write("Printed: ").write;
writeSexp(pTest).writeSexp;
writeln();
}</lang>
{{out}}
Cookies help us deliver our services. By using our services, you agree to our use of cookies.