I've been using OPP to evaluate expressions. It works fine but I'm not sure how to treat the combintions invoked by And/Or/Not/Greater Than/Less Than/Equal.
Does anyone know how? Someone here pointed me in the direction of opp so I'm hoping you're reading, and have already solved it.
Here's the code. Just type an expression and it will give you the result. Left and right () are allowed like normal blitz expressions.
Does anyone know how? Someone here pointed me in the direction of opp so I'm hoping you're reading, and have already solved it.
Here's the code. Just type an expression and it will give you the result. Left and right () are allowed like normal blitz expressions.
Strict Global toke_id=0 Type deli Field id Global cur:TList Field tag Function deliTag( deli$,ntag ) Local del = deli[0] For Local d:deli = EachIn cur If d.id = del d.tag=ntag End If Next End Function Function setcurrent( d:TList ) cur = d End Function Function isDel( in ) For Local de:Deli = EachIn cur If de.id = in Return True Next Return False End Function Function hastag( in ) For Local de:Deli = EachIn cur If de.id = in If de.tag<>0 Return True End If Next Return False End Function Function Create:Deli( word ) Local out:deli = New deli out.id = word Return out End Function Method debug() Print "Delimiter Debug spool:" Print "Actual id:"+id Print "Textural referece "+Chr(id) End Method Function CreateDelis:TList( words$ ) Local dli:TList = CreateList() Local wl = Len(words) For Local j=1 To wl Local d:Deli = deli.create( words[j] ) dli.addlast( d ) Next cur = dli Return dli End Function Function debugList( in:TList ) For Local v:Object = EachIn in Local d:Deli = Deli(v) d.debug() Next End Function End Type Type tokens Field tokes:TList Field toke:Object[] Field ctoke Method set( tok:TList ) tokes = tok toke = tok.toarray() End Method Method NextToken:Token() ctoke:+1 If ctoke>tokes.count() ctoke=tokes.count() Return Null End If Return Token(tokes.valueatindex(ctoke-1)) End Method Function create:Tokens() Return New tokens End Function Method New() tokes = CreateList() End Method Method add( itoke:Token ) tokes.addlast( itoke ) toke = tokes.toarray() End Method Method debug() For Local t:Token = EachIn tokes Print t.id Next End Method End Type Type token Field id$ Function Create:Token( toke$ ) Local out:token = New token out.id = toke Return out End Function Method getlut() Select id Case "+" Return plus Case "-" Return minus Case "*" Return times Case "/" Return devide Case "(" Return scope_entry Case "}" Return scope_exit End Select Return 0 End Method Function CreateTokens:TList( tokes$ ) Local out:TList = CreateList() Local tc = Len(tokes) For Local j=1 To tc Local nt:token = token.create( tokes[j] ) out.addlast( nt ) nt.debug() Next 'Print "Approx " + CountList(out)+"Tokens were defined' Return out End Function Method debug() Print "Token symbolic info" Print id End Method End Type Type tokenizer Function create:tokenizer() Return New tokenizer End Function Method Tokenize:Tokens( text:String ) text = " "+text+" " Local tk:Tokens = tokens.create() Local lvc,fvc lvc=-1 fvc=-1 Local tl= Len(text) Local snc=0,igdot=0 For Local j=0 To tl-1 Local li = text[j] If li = 39 If snc=0 fvc=j+1 snc=1 Else lvc=j-1 snc=0 EndIf EndIf If li>47 And li<58 igdot = True End If Local skpdel=0 If snc=0 If deli.isdel( li ) If igdot = True If li = 46 skpdel=True End If EndIf If Not skpdel If lvc<>fvc And fvc<>-1 If lvc<fvc lvc=fvc Local tst$ = text[fvc..lvc+1] ' Print "Token:"+tst tk.add( token.create( tst ) ) fvc=-1 lvc=-1 EndIf If deli.hastag( li ) tk.add( token.create( Chr(li) ) ) Print "deli "+li+" Had a tag" EndIf igdot=False End If Else If fvc=-1 fvc=j Else lvc=j EndIf EndIf EndIf Next Return tk End Method End Type Const Scope_Entry=1,Scope_Exit=2 Const Assign = 3,Minus=4,Plus=5,Times=7,Devide=8 Const classentry=9,numeric=10,value=11,tend=12 Const reduce=1,shift=2 Global act:Int[,] = New Int[20,20] act[Plus,plus] = reduce act[plus,minus] = reduce act[plus,times] = shift act[plus,devide] = shift act[plus,scope_entry] = shift act[plus,scope_Exit] = reduce act[plus,tend] = reduce act[minus,plus] = reduce act[minus,minus] = reduce act[minus,times] = shift act[minus,devide] = shift act[minus,scope_entry] = shift act[minus,scope_exit] = reduce act[minus,tend] = reduce act[times,plus] = reduce act[times,minus] = reduce act[times,times] = reduce act[times,devide] = reduce act[times,scope_entry] = shift act[times,scope_Exit] = reduce act[times,tend] = reduce act[devide,plus] = reduce act[devide,minus] = reduce act[devide,Times] = reduce act[devide,devide] = reduce act[devide,scope_entry] = shift act[devide,scope_exit] = reduce act[devide,tend ] = reduce act[scope_entry,plus] = shift act[scope_entry,minus] = shift act[scope_entry,times] = shift act[scope_entry,devide] = shift act[scope_entry,scope_Entry] = shift act[scope_Entry,scope_exit] = shift act[scope_Exit,plus] = reduce act[scope_exit,minus] = reduce act[scope_exit,devide] = reduce act[scope_exit,times] = reduce act[scope_Exit,scope_entry] = reduce act[scope_exit,scope_exit] = reduce act[scope_exit,tend] = reduce act[tend,plus] = shift act[tend,minus] = shift act[tend,times] = shift act[tend,devide] = shift act[tend,scope_entry] = shift act[tend,tend] = tend Const delimiters:String = "{}[]';;!@#$%^&*()_+=-/.,?{><\|<> ` " Global maindel:TList = deli.createdelis( delimiters ) deli.delitag( "(",Scope_Entry ) deli.delitag( ")",Scope_Exit ) deli.delitag( "=",Assign ) deli.delitag( "-",Minus) deli.delitag( "+",Plus) deli.delitag( "*",Times) deli.delitag( "/",Devide) deli.delitag( ".",ClassEntry) deli.delitag( "#",Numeric) deli.delitag( ";",TEnd) Type Stack Field Val:Object[5000] Field at Method Push(obj:Object) val[at]=obj at:+1 End Method Method Pop:Object() at:-1 If at<0 at=0 Return val[at] End Method Method Get:Object() If at>0 Return val[at-1] End Method Method size() Return at End Method End Type Type ExpressionParser Field Val:Double[2000],valTop Field Opr:String[2000],oprTop Field tokes:Tokens Method New() End Method Method Parse!( Expr:String ) Local tk:Tokenizer = New Tokenizer tokes:Tokens = tk.tokenize( expr+";" ) valtop=-1 oprtop=0 opr[oprtop]=tend If nxttok() Return 1 Repeat If tok = value If shiftstack() Return 1 Continue End If Select act[Int(opr[oprtop]),tok] Case reduce If reducestack() Return 1 Case shift If shiftstack() Return 1 Case tend If valtop<>0 Print "Syntax error" End If Return val[valtop] Default Print "Unknown combo:" Print opr[oprtop]+":"+tok End End Select Forever End Method Field debug1:String,debug2:String Method nxtTok() Local tokey:Token = tokes.nextToken() If tokey=Null Return 1 debug1 = tokey.id getTok( tokey.id ) End Method Field tokval!,tok Method GetTok(Toke:String) Select toke Case "+" tok=plus Case "-" tok=minus Case "*" tok=times Case "/" tok=devide Case "(" tok=scope_entry Case ")" tok=scope_exit Case ";" tok=tend Default tok=value tokval=Double(toke) End Select End Method Method shiftstack() If tok = value valTop:+1 val[valTop]=tokval Else oprTop:+1 opr[oprtop]=String(tok) EndIf If nxtTok() Return 1 End Method Method Reducestack() Select Int(opr[oprtop]) Case plus val[valtop-1]:+val[valtop] valtop:-1 Case minus val[valtop-1]:-val[valtop] valtop:-1 Case times val[valtop-1]:*val[valtop] valtop:-1 Case devide val[valtop-1]:/val[valtop] valtop:-1 Case scope_exit oprtop:-1 End Select oprtop:-1 End Method End Type Print "Running." While True Local ep:ExpressionParser = New ExpressionParser Print "Answer:"+ep.Parse(Input()) Wend