Arithmetic evaluation: Difference between revisions

Content added Content deleted
m (→‎{{header|PicoLisp}}: minor syntax error)
Line 1,765: Line 1,765:
|> eval
|> eval
|> printfn "%d"</lang>
|> printfn "%d"</lang>

=={{header|FreeBASIC}}==

<lang FreeBASIC>
type Tree
as Tree ptr leftp, rightp
op as string
value as double
end type

dim shared as string sym, usr_input
dim shared tokenval as double

declare function expr(byval p as integer) as Tree ptr

function isdigit(byval ch as string) as long
return (ch <> "") and Asc(ch) >= Asc("0") and Asc(ch) <= Asc("9")
end function

sub error_msg(byval msg as string)
print msg
system
end sub

sub getsym()
do
if len(usr_input) = 0 then
line input usr_input
usr_input += chr(10)
endif
dim as string ch = mid(usr_input, 1, 1)
usr_input = mid(usr_input, 2)

select case ch
case " "
case chr(10), "": sym = "": return
case "+": sym = "+": return
case "-": sym = "-": return
case "*": sym = "*": return
case "/": sym = "/": return
case "(": sym = "(": return
case ")": sym = ")": return
case else
if isdigit(ch) then
dim s as string = ""
dim dot as integer = 0
do
s += ch
if ch = "." then dot += 1
ch = mid(usr_input, 1, 1)
usr_input = mid(usr_input, 2)
loop until not isdigit(ch)
if ch = "." or dot > 1 then error_msg("bogus number")
usr_input = ch + usr_input
tokenval = val(s)
sym = "*number*"
return
end if
sym = "*unknown*"
return
end select
loop
end sub

function make_node(byval op as string, byval leftp as Tree ptr, byval rightp as Tree ptr) as Tree ptr
dim t as Tree ptr

t = callocate(len(Tree))
t->op = op
t->leftp = leftp
t->rightp = rightp
return t
end function

function is_binary(byval op as string) as integer
return op = "*" orelse op = "/" orelse op = "+" orelse op = "-"
end function

function prec(byval op as string) as integer
select case op
case "*unary minus*", "*unary plus*": return 100
case "*", "/": return 90
case "+", "-": return 80
case else: return 0
end select
end function

function primary as Tree ptr
dim t as Tree ptr = 0

select case sym
case "-", "+"
dim op as string = sym
getsym()
t = expr(prec("*unary minus*"))
if op = "-" then return make_node("*unary minus*", t, 0)
if op = "+" then return make_node("*unary plus*", t, 0)
case "("
getsym()
t = expr(0)
if sym <> ")" then error_msg("expecting rparen")
getsym()
return t
case "*number*"
t = make_node(sym, 0, 0)
t->value = tokenval
getsym()
return t
case else: error_msg("expecting a primary")
end select
end function

function expr(byval p as integer) as Tree ptr
dim t as Tree ptr = primary()

while is_binary(sym) andalso prec(sym) >= p
dim t1 as Tree ptr
dim op as string = sym
getsym()
t1 = expr(prec(op) + 1)
t = make_node(op, t, t1)
wend
return t
end function

function eval(byval t as Tree ptr) as double
if t <> 0 then
select case t->op
case "-": return eval(t->leftp) - eval(t->rightp)
case "+": return eval(t->leftp) + eval(t->rightp)
case "*": return eval(t->leftp) * eval(t->rightp)
case "/": return eval(t->leftp) / eval(t->rightp)
case "*unary minus*": return -eval(t->leftp)
case "*unary plus*": return eval(t->leftp)
case "*number*": return t->value
case else: error_msg("unexpected tree node")
end select
end if
return 0
end function

do
getsym()
if sym = "" then continue do
dim t as Tree ptr = expr(0)
print"> "; eval(t)
if sym <> "" then error_msg("unexpected input")
loop
</lang>


=={{header|Go}}==
=={{header|Go}}==