Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; PROJECT : TinySBRunTime
- ; EDITED : 9/5/2016
- ; SimpleMath Extension by LemonWizard
- ; //Usage, SimpleMath("Problem") where the problem is simple operands + - / * and numbers. No spaces.
- ; ---------------------------------------------------------------------
- dim token_types$(25)
- token_types$(1) = "operator"
- token_types$(2) = "keyword"
- token_types$(3) = "variable"
- token_types$(4) = "string"
- Function SimpleMath(problem$)
- //Get the tokens
- //there was a problem with retaining the last position in the string
- //The simplest solution is to always start at a position of 1
- //and chop the string apart >.>
- //It's rude but it is the only solution I can get to work
- dim tokenlist$(100)
- currenttoken=1
- repeat
- sym=false
- tok$, pos, = get_token(problem$, 1)
- if tok$="add" then sym=true
- if tok$="sub" then sym=true
- if tok$="mult" then sym=true
- if tok$="div" then sym=true
- if sym=true then lastlength=1
- if sym=false then lastlength = len(tok$)
- problem$ = cutleft$(problem$, lastlength)
- //print tok$
- tokenlist$(currenttoken) = tok$
- currenttoken+=1 //Increment it
- //print problem$
- until problem$=""
- tokenamount = currenttoken
- value = solve_problem(tokenlist$(), tokenamount)
- endfunction value
- function solve_problem(tokens$(), token_amount )
- //Div Mult
- for t=1 to token_amount
- if tokens$(t) = "div" then sym=true
- if tokens$(t) = "mult" then sym=true
- //Figure out if we have an operand
- if sym=true
- firstvalue$ = tokens$(t-1)
- secondvalue$ = tokens$(t+1)
- firstvalue = val(firstvalue$)
- secondvalue = val(secondvalue$)
- //Add and save the result in the second number. Clear others
- if tokens$(t)="div"
- tokens$(t+1) = str$(firstvalue / secondvalue)
- tokens$(t-1) = "!"
- tokens$(t) = "!"
- endif
- //Subtract and save the result in the second number. Clear others
- if tokens$(t)="mult"
- tokens$(t+1) = str$(firstvalue * secondvalue)
- tokens$(t-1) = "!"
- tokens$(t) = "!"
- endif
- endif
- next t
- //Build a new list
- newcount= 0
- dim newlist$(100)
- For t=1 to token_amount
- if not tokens$(t)="!"
- inc newcount
- newlist$(newcount) = tokens$(t)
- endif
- next t
- //Now we're going to actually run the same code for add or subtract
- //Add / Subtract
- for t=1 to newcount
- if newlist$(t) = "add" then sym=true
- if newlist$(t) = "sub" then sym=true
- //Figure out if we have an operand
- if sym=true
- firstvalue$ = newlist$(t-1)
- secondvalue$ = newlist$(t+1)
- //print secondvalue$
- if secondvalue$ ="!"
- //print "This executes"
- for search=t+1 to newcount
- //Set this straight
- if newlist$(search)<>"!"
- #print newlist$(search)
- newlist$(t+1) = newlist$(search)
- newlist$(search)="!"
- secondvalue$ = newlist$(t+1) //Set it straight for real!
- exitfor
- endif
- next search
- endif
- firstvalue = val(firstvalue$)
- secondvalue = val(secondvalue$)
- //Add and save the result in the second number. Clear others
- if newlist$(t)="add"
- newlist$(t+1) = str$(firstvalue + secondvalue)
- newlist$(t-1) = "!"
- newlist$(t) = "!"
- endif
- //Subtract and save the result in the second number. Clear others
- if newlist$(t)="sub"
- newlist$(t+1) = str$(firstvalue - secondvalue)
- newlist$(t-1) = "!"
- newlist$(t) = "!"
- endif
- endif
- next t
- // Find the solution
- for t=1 to newcount
- Token$ = newlist$(t)
- if Token$<>"!"
- solution = val(Token$)
- #print Token$
- #print solution
- exitfor
- endif
- next t
- endfunction solution
- //Basic maths
- function add(value_a, value_b)
- result = value_a + value_b
- endfunction result
- function subtract(value_a, value_b)
- result = value_a - value_b
- endfunction result
- function divide(value_a, value_b)
- result = value_a / value_b
- endfunction result
- function multiply(value_a, value_b)
- result = value_a / value_b
- endfunction result
- //end of basic maths
- //Single character comparison
- function match(character_s$, character_m$)
- result = false
- if character_s = character_m then result=true
- endfunction result
- function getchar(inputstring$, pos)
- if len(inputstring$) <1
- exitfunction "null"
- endif
- character$ = mid$(inputstring$, pos, 1)
- endfunction character$
- //The step I was missing in my character testing was something similiar to regex where I can testfor each character case by case
- //And make sure that while stepping through the source string to replace that it perfectly matches the target string in EVERY way
- //In other words I have to re-write the mid$ function because it's not trust worthy.. -.-
- function match_sequence(input_string$, match_string$)
- result = false //Always assume false till proven true
- input_length = len(input_string$)
- match_length = len(match_string$)
- //No need to really do anything if the length of the match string is longer than the input string
- if input_length <> match_length
- result = false
- exitfunction result
- endif
- if input_length = match_length
- misses = 0
- for t=1 to input_length
- match_chr$ = getchar(input_string$, t)
- test_chr$ = getchar(match_string$, t)
- if match_chr$ <> test_chr$ then inc matches
- next t
- if matches>1 then result=false
- if matches=0 then result=true
- endif
- endfunction result
- function get_token(input$, position)
- token_$=""
- steps = 0
- for t=position to len(input$)
- char$ = getchar(input$, t)
- if steps=0
- ex=false
- if char$ = "+"
- token_$="add"
- ex=true
- endif
- if char$ = "-"
- token_$="sub"
- ex=true
- endif
- if char$ = "*"
- token_$="mult"
- ex=true
- endif
- if char$ = "/"
- token_$="div"
- ex=true
- endif
- if ex=true
- lastpos = t
- exitfor
- endif
- endif
- //Uh oh we found something that's another token so exit
- //now instead of searching for numbers
- //We just add whatever the character is
- //To the current token.
- //No more dealing with strings directly I hope
- if steps > 0
- ex=false
- if char$ = "+" then ex=true
- if char$ = "-" then ex=true
- if char$ = "*" then ex=true
- if char$ = "/" then ex=true
- lastpos = t
- if ex=true then exitfor
- endif
- //Increment the steps taken here.
- steps = steps + 1
- //Add a character to our token after double-checking if
- //It equals anything already
- result = match_sequence(token_$, "add")
- result = match_sequence(token_$, "sub")
- result = match_sequence(token_$, "mult")
- result = match_sequence(token_$, "div")
- if result=0
- //Now we only add the character to our token IF it's not add sub mult or div
- tokstring$ = token_$ + char$ //Local string char$ should have the last grabbed character which if it's not + - / * it's a number.
- lastpos = t//Save this
- token_$ = tokstring$
- char$=""
- endif
- next t
- //The function will only exit on a few conditions
- //Condition 1, We found a symbol
- //Condition 2, The length of the string ran out
- //Condition 3, the input string is empty
- endfunction token_$, lastpos //return the token.
- function get_tokenFrom(input$, position, tokenslist$())
- token_$=""
- steps = 0
- for t=position to len(input$)
- char$ = getchar(input$, t)
- if steps=0
- ex=false
- if char$ = "+"
- token_$="+"
- ex=true
- endif
- if char$ = "-"
- token_$="-"
- ex=true
- endif
- if char$ = "*"
- token_$="*"
- ex=true
- endif
- if char$ = "/"
- token_$="/"
- ex=true
- endif
- if ex=true
- lastpos = t
- exitfor
- endif
- endif
- //Uh oh we found something that's another token so exit
- //now instead of searching for numbers
- //We just add whatever the character is
- //To the current token.
- //No more dealing with strings directly I hope
- if steps > 0
- ex=false
- if char$ = "+" then ex=true
- if char$ = "-" then ex=true
- if char$ = "*" then ex=true
- if char$ = "/" then ex=true
- if char$ = " "
- tokstring$ =""
- ex=true
- endif
- if char$="="
- tokstring$="="
- ex=true
- endif
- lastpos = t
- if ex=true then exitfor
- endif
- //Increment the steps taken here.
- steps = steps + 1
- //Add a character to our token after double-checking if
- //It equals anything already
- result = match_sequence(token_$, "+")
- result = match_sequence(token_$, "-")
- result = match_sequence(token_$, "*")
- result = match_sequence(token_$, "/")
- if result=false
- //Now we only add the character to our token IF it's not add sub mult or div
- tokstring$ = token_$ + char$ //Local string char$ should have the last grabbed character which if it's not + - / * it's a number.
- lastpos = t//Save this
- token_$ = tokstring$
- char$=""
- //Now we can search depending on the token to find
- TokenCount = getarrayelements( tokenslist$() )
- for n=1 to TokenCount
- r= match_sequence(token_$, tokenslist$(n))
- if r=true
- ex=true
- exitfor
- endif
- next n
- //exit after identifying another token
- if ex=true
- exitfor
- endif
- endif
- next t
- //The function will only exit on a few conditions
- //Condition 1, We found a symbol
- //Condition 2, The length of the string ran out
- //Condition 3, the input string is empty
- endfunction token_$, lastpos //return the token.
- //For right now this doesn't check variable names
- //And will only work on real expressions once parsed
- //IE 'IF 5+1==6 Then Print Hi'
- //A step to extract the values from variable names
- //And replace the tokens with their real values
- //Will solve this, but only with math and variables. There's still commands to parse within expressions and functions
- //This is mostly for handling an expression of the type if expression
- function evaluate_expression(tokenslist$() )
- state=false //Assume false
- comparison = false
- //The comparison operator wasn't found yet
- second_participle=false //All second participles are able to have another recursive call so I only need to do this once I hope
- //Cross your fingers mateys! ARRr! and yer' scurvy harts too!
- error=false //No errors
- tokenamount = getarrayelements(tokenslist$() )
- //Begin the iteration over the tokens to attempt to make sense of the input
- //We expect equals ==
- //We need to find the equals sign
- //Find first occurence of equals sign
- for t=1 to tokenamount
- if tokenslist$(t)="="
- firstsign = t
- exitfor
- endif
- next t
- //We have found the first equal sign.
- //We now need to make sure we are dealing with a comparison
- if tokenslist$(firstsign)="="
- //#print tokenslist$(firstsign)
- //#print tokenslist$(firstsign+1)
- if not tokenslist$(firstsign+1)="="
- print "Expected == operator but found = instead in expression. "
- error=true
- endif
- if tokenslist$(firstsign+1)="="
- comparison=true
- endif
- endif
- //find first occurence of THEN
- for t=firstsign+2 to tokenamount
- if tokenslist$(t)="Then"
- stop_pos=t
- exitfor
- endif
- next t
- //find the if statement
- for t=1 to firstsign-1
- if tokenslist$(t)="IF"
- start_pos=t
- exitfor
- endif
- next t
- //Generate the left string
- for a=start_pos+2 to firstsign-1
- leftside$ = leftside$ + tokenslist$(a)
- next a
- //Generate the right string
- for b=firstsign+2 to stop_pos-1
- rightside$ = rightside$ + tokenslist$(b)
- next b
- //Run them both through simple math
- result_a = simplemath(leftside$)
- result_b = simplemath(rightside$)
- //#print result_a
- //#print result_b
- //Evaluate the situation
- if result_a = result_b then state=true
- if result_a <> result_b then state=false
- if error=true then state=false
- //Return the states
- endfunction state, comparison
- function splitstring_by(input$, position, tokenslist$())
- token_$=""
- steps = 0
- for t=position to len(input$)
- char$ = getchar(input$, t)
- if steps=0
- ex=false
- if ex=true
- lastpos = t
- exitfor
- endif
- endif
- //Uh oh we found something that's another token so exit
- //now instead of searching for numbers
- //We just add whatever the character is
- //To the current token.
- //No more dealing with strings directly I hope
- lastpos = t
- if ex=true then exitfor
- //Increment the steps taken here.
- steps = steps + 1
- //Add a character to our token after double-checking if
- //It equals anything already
- //Now we only add the character to our token IF it's not add sub mult or div
- tokstring$ = token_$ + char$ //Local string char$ should have the last grabbed character which if it's not + - / * it's a number.
- lastpos = t//Save this
- token_$ = tokstring$
- char$=""
- //Now we can search depending on the token to find
- TokenCount = getarrayelements( tokenslist$() )
- for n=1 to TokenCount
- r= match_sequence(token_$, tokenslist$(n))
- if r=true
- ex=true
- exitfor
- endif
- next n
- //exit after identifying another token
- if ex=true
- exitfor
- endif
- next t
- //The function will only exit on a few conditions
- //Condition 1, We found a symbol
- //Condition 2, The length of the string ran out
- //Condition 3, the input string is empty
- endfunction token_$, lastpos //return the token.
- function buildtokenlistfromstring(input$, seperators$())
- dim toklist$(500)
- repeat
- this_token$ = splitstring_by(input$, 1, seperators$())
- toklength = len(this_token$)
- input$ = cutleft$(input$, len(this_token$))
- inc tokenamount
- toklist$(tokenamount)=this_token$
- until input$=""
- endfunction toklist$()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement