Arithmetic evaluation: Difference between revisions

m (add brief documentation for J)
Line 165:
<lang algol68>euler's number is about: 2.71828182845899446428546958</lang>
=={{header|AutoHotkey}}==
{{works with|AutoHotkey_L}}
{{improve|AutoHotkey|Please try and have code hosted on this site.}}
<lang AutoHotkey>/*
See [http://www.autohotkey.com/forum/viewtopic.php?t=17058 this script] on ahk forum.<br>
hand coded recursive descent parser
requires: AutoHotkey version 1.0.46
expr : term ( ( PLUS | MINUS ) term )* ;
term : factor ( ( MULT | DIV ) factor )* ;
factor : NUMBER | '(' expr ')';
*/
 
calcLexer := makeCalcLexer()
string := "((3+4)*(7*9)+3)+4"
tokens := tokenize(string, calcLexer)
msgbox % printTokens(tokens)
ast := expr()
msgbox % printTree(ast)
msgbox % expression := evalTree(ast)
filedelete expression.ahk
fileappend, % "msgbox % " expression, expression.ahk
run, expression.ahk
return
 
 
expr()
{
global tokens
ast := object(1, "expr")
if node := term()
ast._Insert(node)
loop
{
if peek("PLUS") or peek("MINUS")
{
op := getsym()
newop := object(1, op.type, 2, op.value)
node := term()
ast._Insert(newop)
ast._Insert(node)
}
Else
Break
}
return ast
}
 
term()
{
global tokens
tree := object(1, "term")
if node := factor()
tree._Insert(node)
loop
{
if peek("MULT") or peek("DIV")
{
op := getsym()
newop := object(1, op.type, 2, op.value)
node := factor()
tree._Insert(newop)
tree._Insert(node)
}
else
Break
}
return tree
}
 
factor()
{
global tokens
if peek("NUMBER")
{
token := getsym()
tree := object(1, token.type, 2, token.value)
return tree
}
else if peek("OPEN")
{
getsym()
tree := expr()
if peek("CLOSE")
{
getsym()
return tree
}
else
error("miss closing parentheses ")
}
else
error("no factor found")
}
 
peek(type, n=1)
{
global tokens
if (tokens[n, "type"] == type)
return 1
}
 
getsym(n=1)
{
global tokens
return token := tokens._Remove(n)
}
 
error(msg)
{
global tokens
msgbox % msg " at:`n" printToken(tokens[1])
}
 
 
printTree(ast)
{
if !ast
return
 
n := 0
loop
{
n += 1
if !node := ast[n]
break
if !isobject(node)
treeString .= node
else
treeString .= printTree(node)
}
return ("(" treeString ")" )
}
 
evalTree(ast)
{
if !ast
return
 
n := 1
loop
{
n += 1
if !node := ast[n]
break
if !isobject(node)
treeString .= node
else
treeString .= evalTree(node)
}
if (n == 3)
return treeString
return ("(" treeString ")" )
}
 
#include calclex.ahk</lang>
calclex.ahk<lang AutoHotkey>tokenize(string, lexer)
{
stringo := string ; store original string
locationInString := 1
size := strlen(string)
tokens := object()
start:
Enum := Lexer._NewEnum()
While Enum[type, value] ; loop through regular expression lexing rules
{
if (1 == regexmatch(string, value, tokenValue))
{
token := object()
token.pos := locationInString
token.value := tokenValue
token.length := strlen(tokenValue)
token.type := type
tokens._Insert(token)
locationInString += token.length
string := substr(string, token.length + 1)
goto start
}
continue
}
if (locationInString < size)
msgbox % "unrecognized token at " substr(stringo, locationInstring)
return tokens
}
 
makeCalcLexer()
{
calcLexer := object()
PLUS := "\+"
MINUS := "-"
MULT := "\*"
DIV := "/"
OPEN := "\("
CLOSE := "\)"
NUMBER := "\d+"
WS := "[ \t\n]+"
END := "\."
RULES := "PLUS,MINUS,MULT,DIV,OPEN,CLOSE,NUMBER,WS,END"
loop, parse, rules, `,
{
type := A_LoopField
value := %A_LoopField%
calcLexer._Insert(type, value)
}
return calcLexer
}
 
printTokens(tokens)
{
loop % tokens._MaxIndex()
{
tokenString .= printToken(tokens[A_Index]) "`n`n"
}
return tokenString
}
 
 
printToken(token)
{
string := "pos= " token.pos "`nvalue= " token.value "`ntype= " token.type
return string
}</lang>
 
=={{header|C}}==
Anonymous user