Add tasks for all the new languages
This commit is contained in:
parent
9dc3c2bb62
commit
bba7bfd280
13208 changed files with 134745 additions and 0 deletions
3
Task/S-Expressions/Ceylon/s-expressions-1.ceylon
Normal file
3
Task/S-Expressions/Ceylon/s-expressions-1.ceylon
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
module rosetta "1.0.0" {
|
||||
import ceylon.collection "1.2.1";
|
||||
}
|
||||
156
Task/S-Expressions/Ceylon/s-expressions-2.ceylon
Normal file
156
Task/S-Expressions/Ceylon/s-expressions-2.ceylon
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
import ceylon.collection {
|
||||
|
||||
ArrayList
|
||||
}
|
||||
|
||||
class Symbol(shared String text) {
|
||||
string => text;
|
||||
}
|
||||
|
||||
abstract class Node() of Leaf | Branch {}
|
||||
class Leaf(shared String|Integer|Float|Symbol data) extends Node() {
|
||||
string => data.string;
|
||||
}
|
||||
class Branch() extends Node() {
|
||||
shared ArrayList<Node> nodes = ArrayList<Node>();
|
||||
string => nodes.string;
|
||||
}
|
||||
|
||||
shared void run() {
|
||||
|
||||
alias Token => String|Character|Integer|Float|Symbol;
|
||||
|
||||
{Token*} tokenize(String input) {
|
||||
|
||||
class Mode {
|
||||
shared new neutral {}
|
||||
shared new symbol {}
|
||||
shared new quoted {}
|
||||
shared new integer {}
|
||||
shared new float {}
|
||||
shared new escape {}
|
||||
}
|
||||
|
||||
value tokens = ArrayList<Token>();
|
||||
variable value mode = Mode.neutral;
|
||||
value currentToken = StringBuilder();
|
||||
|
||||
void completeToken() {
|
||||
value string = currentToken.string;
|
||||
if(mode == Mode.symbol) {
|
||||
tokens.add(Symbol(string));
|
||||
}
|
||||
if(mode == Mode.quoted) {
|
||||
tokens.add(string);
|
||||
}
|
||||
if(mode == Mode.integer) {
|
||||
assert(exists int = parseInteger(string));
|
||||
tokens.add(int);
|
||||
}
|
||||
if(mode == Mode.float) {
|
||||
assert(exists float = parseFloat(string));
|
||||
tokens.add(float);
|
||||
}
|
||||
mode = Mode.neutral;
|
||||
currentToken.clear();
|
||||
}
|
||||
|
||||
for(char in input) {
|
||||
switch(char)
|
||||
case('(' | ')') {
|
||||
if(mode != Mode.quoted) {
|
||||
completeToken();
|
||||
tokens.add(char);
|
||||
} else {
|
||||
currentToken.appendCharacter(char);
|
||||
}
|
||||
}
|
||||
case('\"') {
|
||||
if(mode == Mode.escape) {
|
||||
currentToken.appendCharacter(char);
|
||||
mode = Mode.quoted;
|
||||
} else if(mode != Mode.quoted) {
|
||||
mode = Mode.quoted;
|
||||
} else if(mode == Mode.quoted) {
|
||||
completeToken();
|
||||
}
|
||||
}
|
||||
case('\\') {
|
||||
if(mode == Mode.quoted) {
|
||||
mode = Mode.escape;
|
||||
} else {
|
||||
currentToken.appendCharacter(char);
|
||||
}
|
||||
}
|
||||
case(' ' | '\n' | '\r') {
|
||||
if(mode != Mode.quoted) {
|
||||
completeToken();
|
||||
} else {
|
||||
currentToken.append(" ");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(mode == Mode.neutral) {
|
||||
if(char.digit) {
|
||||
mode = Mode.integer;
|
||||
} else {
|
||||
mode = Mode.symbol;
|
||||
}
|
||||
}
|
||||
if(mode == Mode.integer && (char == '.' || char == ',')) {
|
||||
mode = Mode.float;
|
||||
}
|
||||
currentToken.appendCharacter(char);
|
||||
}
|
||||
}
|
||||
completeToken();
|
||||
return tokens;
|
||||
}
|
||||
|
||||
Node readFromTokens(ArrayList<Token> tokens) {
|
||||
if(exists first = tokens.accept()) {
|
||||
if(first == '(') {
|
||||
value branch = Branch();
|
||||
while(!tokens.empty) {
|
||||
if(exists token = tokens.first) {
|
||||
if(token == ')') {
|
||||
tokens.accept();
|
||||
break;
|
||||
} else {
|
||||
branch.nodes.add(readFromTokens(tokens));
|
||||
}
|
||||
}
|
||||
}
|
||||
return branch;
|
||||
} else {
|
||||
if(is String|Integer|Float|Symbol first) {
|
||||
return Leaf(first);
|
||||
} else {
|
||||
throw Exception("unexpected token ``first``");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Branch();
|
||||
}
|
||||
}
|
||||
|
||||
void prettyPrint(Node node, Integer indentation = 0) {
|
||||
|
||||
void paddedPrint(String s) => print(" ".repeat(indentation) + s);
|
||||
|
||||
if(is Leaf node) {
|
||||
paddedPrint(node.string);
|
||||
} else {
|
||||
paddedPrint("(");
|
||||
for(n in node.nodes) {
|
||||
prettyPrint(n, indentation + 2);
|
||||
}
|
||||
paddedPrint(")");
|
||||
}
|
||||
}
|
||||
|
||||
value tokens = tokenize("""((data "quoted data" 123 4.5)
|
||||
(data (!@# (4.5) "(more" "data)")))""");
|
||||
value tree = readFromTokens(ArrayList {*tokens});
|
||||
prettyPrint(tree);
|
||||
}
|
||||
16
Task/S-Expressions/EchoLisp/s-expressions.echolisp
Normal file
16
Task/S-Expressions/EchoLisp/s-expressions.echolisp
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
(define input-string #'((data "quoted data" 123 4.5)\n(data (!@# (4.5) "(more" "data)")))'#)
|
||||
|
||||
input-string
|
||||
→ "((data "quoted data" 123 4.5)
|
||||
(data (!@# (4.5) "(more" "data)")))"
|
||||
|
||||
(define s-expr (read-from-string input-string))
|
||||
s-expr
|
||||
→ ((data "quoted data" 123 4.5) (data (!@# (4.5) "(more" "data)")))
|
||||
|
||||
(first s-expr)
|
||||
→ (data "quoted data" 123 4.5)
|
||||
(first(first s-expr))
|
||||
→ data
|
||||
(first(rest s-expr))
|
||||
→ (data (!@# (4.5) "(more" "data)"))
|
||||
84
Task/S-Expressions/Phix/s-expressions.phix
Normal file
84
Task/S-Expressions/Phix/s-expressions.phix
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
constant s_expr_str = """
|
||||
((data "quoted data" 123 4.5)
|
||||
(data (!@# (4.5) "(more" "data)")))"""
|
||||
|
||||
function skip_spaces(string s, integer sidx)
|
||||
while sidx<=length(s) and find(s[sidx]," \t\r\n") do sidx += 1 end while
|
||||
return sidx
|
||||
end function
|
||||
|
||||
function get_term(string s, integer sidx)
|
||||
-- get a single quoted string, symbol, or number.
|
||||
integer ch = s[sidx]
|
||||
string res = ""
|
||||
if ch='\"' then
|
||||
res &= ch
|
||||
while 1 do
|
||||
sidx += 1
|
||||
ch = s[sidx]
|
||||
res &= ch
|
||||
if ch='\\' then
|
||||
sidx += 1
|
||||
ch = s[sidx]
|
||||
res &= ch
|
||||
elsif ch='\"' then
|
||||
sidx += 1
|
||||
exit
|
||||
end if
|
||||
end while
|
||||
else
|
||||
integer asnumber = (ch>='0' and ch<='9')
|
||||
while not find(ch,") \t\r\n") do
|
||||
res &= ch
|
||||
sidx += 1
|
||||
if sidx>length(s) then exit end if
|
||||
ch = s[sidx]
|
||||
end while
|
||||
if asnumber then
|
||||
sequence scanres = scanf(res,"%f")
|
||||
if length(scanres)=1 then return {scanres[1][1],sidx} end if
|
||||
-- error? (failed to parse number)
|
||||
end if
|
||||
end if
|
||||
return {res,sidx}
|
||||
end function
|
||||
|
||||
function parse_s_expr(string s, integer sidx)
|
||||
integer ch = s[sidx]
|
||||
sequence res = {}
|
||||
object element
|
||||
if ch!='(' then ?9/0 end if
|
||||
sidx += 1
|
||||
while 1 do
|
||||
sidx = skip_spaces(s,sidx)
|
||||
-- error? (if past end of string/missing ')')
|
||||
ch = s[sidx]
|
||||
if ch=')' then exit end if
|
||||
if ch='(' then
|
||||
{element,sidx} = parse_s_expr(s,sidx)
|
||||
else
|
||||
{element,sidx} = get_term(s,sidx)
|
||||
end if
|
||||
res = append(res,element)
|
||||
end while
|
||||
sidx = skip_spaces(s,sidx+1)
|
||||
return {res,sidx}
|
||||
end function
|
||||
|
||||
sequence s_expr
|
||||
integer sidx
|
||||
{s_expr,sidx} = parse_s_expr(s_expr_str,1)
|
||||
if sidx<=length(s_expr_str) then
|
||||
printf(1,"incomplete parse(\"%s\")\n",{s_expr_str[sidx..$]})
|
||||
end if
|
||||
|
||||
puts(1,"\nThe string:\n")
|
||||
?s_expr_str
|
||||
|
||||
puts(1,"\nDefault pretty printing:\n")
|
||||
--?s_expr
|
||||
pp(s_expr)
|
||||
|
||||
puts(1,"\nBespoke pretty printing:\n")
|
||||
--ppEx(s_expr,{pp_Nest,1,pp_StrFmt,-3,pp_Brkt,"()"})
|
||||
ppEx(s_expr,{pp_Nest,4,pp_StrFmt,-3,pp_Brkt,"()"})
|
||||
72
Task/S-Expressions/Potion/s-expressions.potion
Normal file
72
Task/S-Expressions/Potion/s-expressions.potion
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
isdigit = (c): 47 < c ord and c ord < 58.
|
||||
iswhitespace = (c): c ord == 10 or c ord == 13 or c == " ".
|
||||
|
||||
# str: a string of the form "...<nondigit>[{<symb>}]..."
|
||||
# i: index to start at (must be the index of <nondigit>)
|
||||
# => returns (<the symbol as a string>, <index after the last char>)
|
||||
parsesymbol = (str, i) :
|
||||
datum = ()
|
||||
while (str(i) != "(" and str(i) != ")" and not iswhitespace(str(i)) and str(i) != "\"") :
|
||||
datum append(str(i++))
|
||||
.
|
||||
(datum join, i)
|
||||
.
|
||||
|
||||
# str: a string of the form "...[<minus>]{<digit>}[<dot>{<digit>}]..."
|
||||
# i: index to start at (must be the index of the first token)
|
||||
# => returns (<float or int>, <index after the last digit>)
|
||||
parsenumber = (str, i) :
|
||||
datum = ()
|
||||
dot = false
|
||||
while (str(i) != "(" and str(i) != ")" and not iswhitespace(str(i)) and str(i) != "\"") :
|
||||
if (str(i) == "."): dot = true.
|
||||
datum append(str(i++))
|
||||
.
|
||||
if (dot): (datum join number, i).
|
||||
else: (datum join number integer, i).
|
||||
.
|
||||
|
||||
# str: a string of the form "...\"....\"..."
|
||||
# i: index to start at (must be the index of the first quote)
|
||||
# => returns (<the string>, <index after the last quote>)
|
||||
parsestring = (str, i) :
|
||||
datum = ("\"")
|
||||
while (str(++i) != "\"") :
|
||||
datum append(str(i))
|
||||
.
|
||||
datum append("\"")
|
||||
(datum join, ++i)
|
||||
.
|
||||
|
||||
# str: a string of the form "...(...)..."
|
||||
# i: index to start at
|
||||
# => returns (<tuple/list>, <index after the last paren>)
|
||||
parselist = (str, i) :
|
||||
lst = ()
|
||||
data = ()
|
||||
while (str(i) != "("): i++.
|
||||
i++
|
||||
while (str(i) != ")") :
|
||||
if (not iswhitespace(str(i))) :
|
||||
if (isdigit(str(i)) or (str(i) == "-" and isdigit(str(i + 1)))): data = parsenumber(str, i).
|
||||
elsif (str(i) == "\""): data = parsestring(str, i).
|
||||
elsif (str(i) == "("): data = parselist(str, i).
|
||||
else: data = parsesymbol(str, i).
|
||||
lst append(data(0))
|
||||
i = data(1)
|
||||
. else :
|
||||
++i
|
||||
.
|
||||
.
|
||||
(lst, ++i)
|
||||
.
|
||||
|
||||
parsesexpr = (str) :
|
||||
parselist(str, 0)(0)
|
||||
.
|
||||
|
||||
parsesexpr("(define (factorial x) \"compute factorial\" (version 2.0) (apply * (range 1 x)))") string print
|
||||
"\n" print
|
||||
parsesexpr("((data \"quoted data\" 123 4.5)
|
||||
(data (!@# (4.5) \"(more\" \"data)\")))") string print
|
||||
"\n" print
|
||||
47
Task/S-Expressions/Sidef/s-expressions.sidef
Normal file
47
Task/S-Expressions/Sidef/s-expressions.sidef
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
var t = frequire('Text::Balanced');
|
||||
|
||||
func sexpr(txt) {
|
||||
txt.trim!;
|
||||
|
||||
var m = txt.match(/^\((.*)\)$/s) || die "Invalid: <<#{txt}>>";
|
||||
txt = m[0];
|
||||
|
||||
var w;
|
||||
var ret = [];
|
||||
while (!txt.is_empty) {
|
||||
given (txt.first) {
|
||||
when('(') {
|
||||
(w, txt) = t.extract_bracketed(txt, '()');
|
||||
w = sexpr(w);
|
||||
}
|
||||
when ('"') {
|
||||
(w, txt) = t.extract_delimited(txt, '"')
|
||||
w.sub!(/^"(.*)"/, {|s1| s1 });
|
||||
}
|
||||
default {
|
||||
txt.sub!(/^(\S+)/, {|s1| w = s1; '' });
|
||||
}
|
||||
}
|
||||
ret << w;
|
||||
txt.trim_beg!;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
func sexpr2txt(String e) {
|
||||
e ~~ /[\s"\(\)]/ ? do { e.gsub!('"', '\\"'); %Q("#{e}") } : e;
|
||||
}
|
||||
|
||||
func sexpr2txt(expr) {
|
||||
'(' + expr.map {|e| sexpr2txt(e) }.join(' ') + ')';
|
||||
}
|
||||
|
||||
var s = sexpr(%q{
|
||||
|
||||
((data "quoted data" 123 4.5)
|
||||
(data (!@# (4.5) "(more" "data)")))
|
||||
|
||||
});
|
||||
|
||||
say s; # dump structure
|
||||
say sexpr2txt(s); # convert back
|
||||
Loading…
Add table
Add a link
Reference in a new issue