S-expressions: Difference between revisions

Content added Content deleted
m (→‎JavaScript :: Functional: (typo fixed in preamble))
(Added 11l)
Line 32: Line 32:
Let the writer produce pretty printed output with indenting and line-breaks.
Let the writer produce pretty printed output with indenting and line-breaks.
<br><br>
<br><br>

=={{header|11l}}==
{{trans|Nim}}

<lang 11l>T Token
T.enum Kind
INT
FLOAT
STRING
IDENT
LPAR
RPAR
END

Kind kind
String val

F (kind, val = ‘’)
.kind = kind
.val = val

F lex(input_str)
[Token] result
V pos = 0

F current()
R I @pos < @input_str.len {@input_str[@pos]} E Char("\0")

L pos < input_str.len
V ch = input_str[pos]
I ch == ‘(’
pos++
result.append(Token(Token.Kind.LPAR))
E I ch == ‘)’
pos++
result.append(Token(Token.Kind.RPAR))
E I ch C ‘0’..‘9’
V num = ‘’
V kind = Token.Kind.INT
L current() C ‘0’..‘9’
num ‘’= current()
pos++
I current() == ‘.’
num ‘’= current()
kind = FLOAT
pos++
L current() C ‘0’..‘9’
num ‘’= current()
pos++
result.append(Token(kind, num))
E I ch C (‘ ’, "\t", "\n", "\r")
pos++
E I ch == ‘"’
V str = ‘’
pos++
L current() != ‘"’
str ‘’= current()
pos++
pos++
result.append(Token(Token.Kind.STRING, str))
E
V BannedChars = Set([‘ ’, "\t", ‘"’, ‘(’, ‘)’, ‘;’])
V ident = ‘’
L current() !C BannedChars
ident ‘’= current()
pos++
result.append(Token(Token.Kind.IDENT, ident))

result.append(Token(Token.Kind.END))
R result

F indent(s, count)
R (count * ‘ ’)‘’s.replace("\n", "\n"(count * ‘ ’))

T SExpr
T.enum Kind
INT
FLOAT
STRING
IDENT
LIST

Kind kind
String val
[SExpr] children

F (kind, val = ‘’)
.kind = kind
.val = val

F to_str()
I .kind C (SExpr.Kind.INT, SExpr.Kind.FLOAT, SExpr.Kind.IDENT)
R .val
E I .kind == STRING
R ‘"’(.val)‘"’
E I .kind == LIST
V result = ‘(’
L(i, ex) enumerate(.children)
I ex.kind == LIST & ex.children.len > 1
result ‘’= "\n"
result ‘’= indent(ex.to_str(), 2)
E
I i > 0
result ‘’= ‘ ’
result ‘’= ex.to_str()
R result‘)’
assert(0B)

V input_str = ‘
((data "quoted data" 123 4.5)
(data (!@# (4.5) "(more" "data)")))
V tokens = lex(input_str)
V pos = 0

F current()
R I :pos < :tokens.len {:tokens[:pos]} E Token(Token.Kind.END)

F parse() -> SExpr
V token = current()
:pos++
I token.kind == INT
R SExpr(SExpr.Kind.INT, token.val)
E I token.kind == FLOAT
R SExpr(SExpr.Kind.FLOAT, token.val)
E I token.kind == STRING
R SExpr(SExpr.Kind.STRING, token.val)
E I token.kind == IDENT
R SExpr(SExpr.Kind.IDENT, token.val)
E I token.kind == LPAR
V result = SExpr(SExpr.Kind.LIST)
L current().kind !C (Token.Kind.RPAR, Token.Kind.END)
result.children.append(parse())
assert(current().kind != END, ‘Missing right paren ')'’)
:pos++
R result
assert(0B)

print(parse().to_str())</lang>

{{out}}
<pre>
(
(data "quoted data" 123 4.5)
(data
(!@# (4.5) "(more" "data)")))
</pre>


=={{header|Ada}}==
=={{header|Ada}}==