Arithmetic evaluation: Difference between revisions

m
Line 1,154:
=={{header|Dyalect}}==
 
<lang swiftdyalect>type Expr = Bin(op, Expr left, Expr right) or Literal(Float val)
type Token(val, Char kind)
func Token.toStringToString() => this::.val.toStringToString()
 
func tokenize(str) {
func isSep(c) =>
c is '+' or '-' or '*' or '/' or ' ' or '\t' or '\n' or '\r' or '(' or ')' or '\0'
var idx = -1
let len = str.lenLength()
let tokens = []
func next() {
idx += 1
Line 1,171:
str[idx]
}
while true {
let c = next()
match c {
'\0' => { break },
'+' => tokens.addAdd(Token(c, '+')),
'-' => tokens.addAdd(Token(c, '-')),
'*' => tokens.addAdd(Token(c, '*')),
'/' => tokens.addAdd(Token(c, '/')),
'(' => tokens.addAdd(Token(c, '(')),
')' => tokens.addAdd(Token(c, ')')),
_ => {
let i = idx
while !isSep(next()) { }
idx -= 1
tokens.addAdd(Token(Float.parseParse(str[i..idx]), 'F'))
}
}
}
tokens
}
 
func parse(tokens) {
var idx = -1
let len = tokens.lenLength()
let eol = Token(val: nil, kind: 'E')
func pop() {
Line 1,210:
}
func expect(kind) {
peek()::.kind == kind
}
var add_or_sub1
func literal() {
return false when !expect('F')
Expr.Literal(pop()::.val)
}
func group() {
return false when !expect('(')
Line 1,227:
ret
}
func mul_or_div() {
var fst = group()
fst = literal() when !fst
return fst when !expect('*') && !expect('/')
let op = pop()::.val
var snd = group()
snd = literal() when !snd
Expr.Bin(op, fst, snd)
}
func add_or_sub() {
let fst = mul_or_div()
return fst when !expect('+') && !expect('-')
let op = pop()::.val
let snd = mul_or_div()
Expr.Bin(op, fst, snd)
}
add_or_sub1 = add_or_sub
add_or_sub()
}
 
func exec(ast) {
match ast {
Line 1,261:
}
}
 
func eval(str) {
let tokens = tokenize(str)
Line 1,267:
exec(ast)
}
 
print( eval("(1+33.23)*7") )
print( eval("1+33.23*7") )</lang>
Anonymous user