Advertisement
Guest User

SimpleMath

a guest
Sep 9th, 2016
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.36 KB | None | 0 0
  1. ; PROJECT : TinySBRunTime
  2. ; EDITED : 9/5/2016
  3. ; SimpleMath Extension by LemonWizard
  4. ; //Usage, SimpleMath("Problem") where the problem is simple operands + - / * and numbers. No spaces.
  5. ; ---------------------------------------------------------------------
  6.  
  7. dim token_types$(25)
  8. token_types$(1) = "operator"
  9. token_types$(2) = "keyword"
  10. token_types$(3) = "variable"
  11. token_types$(4) = "string"
  12.  
  13.  
  14.  
  15.  
  16. Function SimpleMath(problem$)
  17. //Get the tokens
  18.  
  19. //there was a problem with retaining the last position in the string
  20. //The simplest solution is to always start at a position of 1
  21. //and chop the string apart >.>
  22. //It's rude but it is the only solution I can get to work
  23.  
  24. dim tokenlist$(100)
  25. currenttoken=1
  26.  
  27. repeat
  28. sym=false
  29. tok$, pos, = get_token(problem$, 1)
  30. if tok$="add" then sym=true
  31. if tok$="sub" then sym=true
  32. if tok$="mult" then sym=true
  33. if tok$="div" then sym=true
  34. if sym=true then lastlength=1
  35. if sym=false then lastlength = len(tok$)
  36.  
  37. problem$ = cutleft$(problem$, lastlength)
  38.  
  39. //print tok$
  40. tokenlist$(currenttoken) = tok$
  41. currenttoken+=1 //Increment it
  42. //print problem$
  43.  
  44. until problem$=""
  45.  
  46.  
  47.  
  48. tokenamount = currenttoken
  49.  
  50. value = solve_problem(tokenlist$(), tokenamount)
  51. endfunction value
  52.  
  53.  
  54.  
  55. function solve_problem(tokens$(), token_amount )
  56.  
  57. //Div Mult
  58. for t=1 to token_amount
  59.  
  60. if tokens$(t) = "div" then sym=true
  61. if tokens$(t) = "mult" then sym=true
  62.  
  63. //Figure out if we have an operand
  64. if sym=true
  65.  
  66. firstvalue$ = tokens$(t-1)
  67. secondvalue$ = tokens$(t+1)
  68. firstvalue = val(firstvalue$)
  69. secondvalue = val(secondvalue$)
  70.  
  71. //Add and save the result in the second number. Clear others
  72. if tokens$(t)="div"
  73.  
  74.  
  75. tokens$(t+1) = str$(firstvalue / secondvalue)
  76. tokens$(t-1) = "!"
  77. tokens$(t) = "!"
  78.  
  79. endif
  80.  
  81. //Subtract and save the result in the second number. Clear others
  82. if tokens$(t)="mult"
  83.  
  84. tokens$(t+1) = str$(firstvalue * secondvalue)
  85. tokens$(t-1) = "!"
  86. tokens$(t) = "!"
  87.  
  88. endif
  89.  
  90.  
  91. endif
  92.  
  93.  
  94. next t
  95.  
  96.  
  97. //Build a new list
  98. newcount= 0
  99. dim newlist$(100)
  100. For t=1 to token_amount
  101.  
  102. if not tokens$(t)="!"
  103. inc newcount
  104. newlist$(newcount) = tokens$(t)
  105. endif
  106.  
  107. next t
  108.  
  109.  
  110. //Now we're going to actually run the same code for add or subtract
  111.  
  112. //Add / Subtract
  113. for t=1 to newcount
  114.  
  115. if newlist$(t) = "add" then sym=true
  116. if newlist$(t) = "sub" then sym=true
  117.  
  118. //Figure out if we have an operand
  119. if sym=true
  120.  
  121. firstvalue$ = newlist$(t-1)
  122. secondvalue$ = newlist$(t+1)
  123.  
  124. //print secondvalue$
  125. if secondvalue$ ="!"
  126. //print "This executes"
  127. for search=t+1 to newcount
  128.  
  129.  
  130. //Set this straight
  131. if newlist$(search)<>"!"
  132. #print newlist$(search)
  133. newlist$(t+1) = newlist$(search)
  134. newlist$(search)="!"
  135. secondvalue$ = newlist$(t+1) //Set it straight for real!
  136. exitfor
  137. endif
  138.  
  139.  
  140. next search
  141.  
  142.  
  143. endif
  144.  
  145.  
  146. firstvalue = val(firstvalue$)
  147. secondvalue = val(secondvalue$)
  148.  
  149. //Add and save the result in the second number. Clear others
  150. if newlist$(t)="add"
  151.  
  152.  
  153. newlist$(t+1) = str$(firstvalue + secondvalue)
  154. newlist$(t-1) = "!"
  155. newlist$(t) = "!"
  156.  
  157. endif
  158.  
  159. //Subtract and save the result in the second number. Clear others
  160. if newlist$(t)="sub"
  161.  
  162. newlist$(t+1) = str$(firstvalue - secondvalue)
  163. newlist$(t-1) = "!"
  164. newlist$(t) = "!"
  165.  
  166. endif
  167.  
  168.  
  169. endif
  170.  
  171.  
  172. next t
  173.  
  174.  
  175. // Find the solution
  176. for t=1 to newcount
  177. Token$ = newlist$(t)
  178. if Token$<>"!"
  179. solution = val(Token$)
  180. #print Token$
  181. #print solution
  182. exitfor
  183. endif
  184.  
  185.  
  186. next t
  187.  
  188. endfunction solution
  189.  
  190. //Basic maths
  191. function add(value_a, value_b)
  192.  
  193. result = value_a + value_b
  194.  
  195. endfunction result
  196.  
  197. function subtract(value_a, value_b)
  198.  
  199. result = value_a - value_b
  200.  
  201. endfunction result
  202.  
  203. function divide(value_a, value_b)
  204.  
  205. result = value_a / value_b
  206.  
  207. endfunction result
  208.  
  209. function multiply(value_a, value_b)
  210.  
  211. result = value_a / value_b
  212.  
  213. endfunction result
  214.  
  215. //end of basic maths
  216.  
  217.  
  218. //Single character comparison
  219. function match(character_s$, character_m$)
  220. result = false
  221.  
  222. if character_s = character_m then result=true
  223. endfunction result
  224.  
  225.  
  226. function getchar(inputstring$, pos)
  227. if len(inputstring$) <1
  228. exitfunction "null"
  229. endif
  230.  
  231. character$ = mid$(inputstring$, pos, 1)
  232.  
  233. endfunction character$
  234.  
  235.  
  236. //The step I was missing in my character testing was something similiar to regex where I can testfor each character case by case
  237. //And make sure that while stepping through the source string to replace that it perfectly matches the target string in EVERY way
  238. //In other words I have to re-write the mid$ function because it's not trust worthy.. -.-
  239. function match_sequence(input_string$, match_string$)
  240.  
  241. result = false //Always assume false till proven true
  242.  
  243. input_length = len(input_string$)
  244. match_length = len(match_string$)
  245. //No need to really do anything if the length of the match string is longer than the input string
  246. if input_length <> match_length
  247. result = false
  248. exitfunction result
  249. endif
  250.  
  251. if input_length = match_length
  252.  
  253. misses = 0
  254. for t=1 to input_length
  255.  
  256. match_chr$ = getchar(input_string$, t)
  257. test_chr$ = getchar(match_string$, t)
  258. if match_chr$ <> test_chr$ then inc matches
  259.  
  260. next t
  261.  
  262. if matches>1 then result=false
  263. if matches=0 then result=true
  264. endif
  265.  
  266. endfunction result
  267.  
  268. function get_token(input$, position)
  269.  
  270. token_$=""
  271. steps = 0
  272. for t=position to len(input$)
  273. char$ = getchar(input$, t)
  274.  
  275. if steps=0
  276. ex=false
  277. if char$ = "+"
  278. token_$="add"
  279. ex=true
  280. endif
  281.  
  282. if char$ = "-"
  283. token_$="sub"
  284. ex=true
  285. endif
  286.  
  287. if char$ = "*"
  288. token_$="mult"
  289. ex=true
  290. endif
  291.  
  292. if char$ = "/"
  293. token_$="div"
  294. ex=true
  295. endif
  296.  
  297. if ex=true
  298. lastpos = t
  299. exitfor
  300. endif
  301.  
  302. endif
  303.  
  304. //Uh oh we found something that's another token so exit
  305. //now instead of searching for numbers
  306. //We just add whatever the character is
  307. //To the current token.
  308. //No more dealing with strings directly I hope
  309. if steps > 0
  310. ex=false
  311. if char$ = "+" then ex=true
  312. if char$ = "-" then ex=true
  313. if char$ = "*" then ex=true
  314. if char$ = "/" then ex=true
  315. lastpos = t
  316. if ex=true then exitfor
  317. endif
  318.  
  319. //Increment the steps taken here.
  320. steps = steps + 1
  321. //Add a character to our token after double-checking if
  322. //It equals anything already
  323. result = match_sequence(token_$, "add")
  324. result = match_sequence(token_$, "sub")
  325. result = match_sequence(token_$, "mult")
  326. result = match_sequence(token_$, "div")
  327.  
  328.  
  329. if result=0
  330. //Now we only add the character to our token IF it's not add sub mult or div
  331. tokstring$ = token_$ + char$ //Local string char$ should have the last grabbed character which if it's not + - / * it's a number.
  332. lastpos = t//Save this
  333. token_$ = tokstring$
  334. char$=""
  335.  
  336. endif
  337. next t
  338.  
  339.  
  340. //The function will only exit on a few conditions
  341. //Condition 1, We found a symbol
  342. //Condition 2, The length of the string ran out
  343. //Condition 3, the input string is empty
  344.  
  345. endfunction token_$, lastpos //return the token.
  346.  
  347. function get_tokenFrom(input$, position, tokenslist$())
  348.  
  349. token_$=""
  350. steps = 0
  351. for t=position to len(input$)
  352. char$ = getchar(input$, t)
  353.  
  354. if steps=0
  355. ex=false
  356. if char$ = "+"
  357. token_$="+"
  358. ex=true
  359. endif
  360.  
  361. if char$ = "-"
  362. token_$="-"
  363. ex=true
  364. endif
  365.  
  366. if char$ = "*"
  367. token_$="*"
  368. ex=true
  369. endif
  370.  
  371. if char$ = "/"
  372. token_$="/"
  373. ex=true
  374. endif
  375.  
  376.  
  377. if ex=true
  378. lastpos = t
  379. exitfor
  380. endif
  381.  
  382. endif
  383.  
  384. //Uh oh we found something that's another token so exit
  385. //now instead of searching for numbers
  386. //We just add whatever the character is
  387. //To the current token.
  388. //No more dealing with strings directly I hope
  389. if steps > 0
  390. ex=false
  391. if char$ = "+" then ex=true
  392. if char$ = "-" then ex=true
  393. if char$ = "*" then ex=true
  394. if char$ = "/" then ex=true
  395. if char$ = " "
  396. tokstring$ =""
  397. ex=true
  398. endif
  399.  
  400. if char$="="
  401. tokstring$="="
  402. ex=true
  403. endif
  404.  
  405.  
  406. lastpos = t
  407. if ex=true then exitfor
  408. endif
  409.  
  410. //Increment the steps taken here.
  411. steps = steps + 1
  412. //Add a character to our token after double-checking if
  413. //It equals anything already
  414. result = match_sequence(token_$, "+")
  415. result = match_sequence(token_$, "-")
  416. result = match_sequence(token_$, "*")
  417. result = match_sequence(token_$, "/")
  418.  
  419. if result=false
  420. //Now we only add the character to our token IF it's not add sub mult or div
  421.  
  422. tokstring$ = token_$ + char$ //Local string char$ should have the last grabbed character which if it's not + - / * it's a number.
  423.  
  424. lastpos = t//Save this
  425. token_$ = tokstring$
  426. char$=""
  427.  
  428. //Now we can search depending on the token to find
  429. TokenCount = getarrayelements( tokenslist$() )
  430. for n=1 to TokenCount
  431.  
  432. r= match_sequence(token_$, tokenslist$(n))
  433. if r=true
  434. ex=true
  435. exitfor
  436. endif
  437.  
  438.  
  439. next n
  440. //exit after identifying another token
  441. if ex=true
  442. exitfor
  443. endif
  444.  
  445. endif
  446. next t
  447.  
  448.  
  449. //The function will only exit on a few conditions
  450. //Condition 1, We found a symbol
  451. //Condition 2, The length of the string ran out
  452. //Condition 3, the input string is empty
  453.  
  454. endfunction token_$, lastpos //return the token.
  455.  
  456. //For right now this doesn't check variable names
  457. //And will only work on real expressions once parsed
  458. //IE 'IF 5+1==6 Then Print Hi'
  459. //A step to extract the values from variable names
  460. //And replace the tokens with their real values
  461. //Will solve this, but only with math and variables. There's still commands to parse within expressions and functions
  462.  
  463.  
  464. //This is mostly for handling an expression of the type if expression
  465. function evaluate_expression(tokenslist$() )
  466. state=false //Assume false
  467. comparison = false
  468. //The comparison operator wasn't found yet
  469. second_participle=false //All second participles are able to have another recursive call so I only need to do this once I hope
  470. //Cross your fingers mateys! ARRr! and yer' scurvy harts too!
  471. error=false //No errors
  472.  
  473. tokenamount = getarrayelements(tokenslist$() )
  474.  
  475. //Begin the iteration over the tokens to attempt to make sense of the input
  476. //We expect equals ==
  477. //We need to find the equals sign
  478.  
  479. //Find first occurence of equals sign
  480. for t=1 to tokenamount
  481. if tokenslist$(t)="="
  482. firstsign = t
  483. exitfor
  484. endif
  485.  
  486. next t
  487.  
  488. //We have found the first equal sign.
  489. //We now need to make sure we are dealing with a comparison
  490. if tokenslist$(firstsign)="="
  491. //#print tokenslist$(firstsign)
  492. //#print tokenslist$(firstsign+1)
  493.  
  494. if not tokenslist$(firstsign+1)="="
  495. print "Expected == operator but found = instead in expression. "
  496. error=true
  497. endif
  498.  
  499. if tokenslist$(firstsign+1)="="
  500. comparison=true
  501. endif
  502. endif
  503.  
  504.  
  505. //find first occurence of THEN
  506. for t=firstsign+2 to tokenamount
  507. if tokenslist$(t)="Then"
  508. stop_pos=t
  509. exitfor
  510. endif
  511. next t
  512.  
  513.  
  514.  
  515. //find the if statement
  516. for t=1 to firstsign-1
  517. if tokenslist$(t)="IF"
  518. start_pos=t
  519. exitfor
  520. endif
  521. next t
  522.  
  523.  
  524. //Generate the left string
  525. for a=start_pos+2 to firstsign-1
  526. leftside$ = leftside$ + tokenslist$(a)
  527. next a
  528.  
  529. //Generate the right string
  530. for b=firstsign+2 to stop_pos-1
  531. rightside$ = rightside$ + tokenslist$(b)
  532. next b
  533.  
  534. //Run them both through simple math
  535. result_a = simplemath(leftside$)
  536. result_b = simplemath(rightside$)
  537.  
  538. //#print result_a
  539. //#print result_b
  540.  
  541. //Evaluate the situation
  542. if result_a = result_b then state=true
  543. if result_a <> result_b then state=false
  544.  
  545.  
  546.  
  547.  
  548.  
  549. if error=true then state=false
  550.  
  551.  
  552. //Return the states
  553. endfunction state, comparison
  554.  
  555. function splitstring_by(input$, position, tokenslist$())
  556.  
  557. token_$=""
  558. steps = 0
  559. for t=position to len(input$)
  560. char$ = getchar(input$, t)
  561.  
  562. if steps=0
  563. ex=false
  564.  
  565. if ex=true
  566. lastpos = t
  567. exitfor
  568. endif
  569.  
  570. endif
  571.  
  572. //Uh oh we found something that's another token so exit
  573. //now instead of searching for numbers
  574. //We just add whatever the character is
  575. //To the current token.
  576. //No more dealing with strings directly I hope
  577.  
  578. lastpos = t
  579. if ex=true then exitfor
  580.  
  581.  
  582. //Increment the steps taken here.
  583. steps = steps + 1
  584. //Add a character to our token after double-checking if
  585. //It equals anything already
  586.  
  587. //Now we only add the character to our token IF it's not add sub mult or div
  588.  
  589. tokstring$ = token_$ + char$ //Local string char$ should have the last grabbed character which if it's not + - / * it's a number.
  590.  
  591. lastpos = t//Save this
  592. token_$ = tokstring$
  593. char$=""
  594.  
  595. //Now we can search depending on the token to find
  596. TokenCount = getarrayelements( tokenslist$() )
  597. for n=1 to TokenCount
  598.  
  599. r= match_sequence(token_$, tokenslist$(n))
  600. if r=true
  601. ex=true
  602. exitfor
  603. endif
  604.  
  605.  
  606. next n
  607. //exit after identifying another token
  608. if ex=true
  609. exitfor
  610. endif
  611.  
  612. next t
  613.  
  614.  
  615. //The function will only exit on a few conditions
  616. //Condition 1, We found a symbol
  617. //Condition 2, The length of the string ran out
  618. //Condition 3, the input string is empty
  619.  
  620. endfunction token_$, lastpos //return the token.
  621.  
  622. function buildtokenlistfromstring(input$, seperators$())
  623. dim toklist$(500)
  624. repeat
  625. this_token$ = splitstring_by(input$, 1, seperators$())
  626.  
  627. toklength = len(this_token$)
  628. input$ = cutleft$(input$, len(this_token$))
  629.  
  630. inc tokenamount
  631. toklist$(tokenamount)=this_token$
  632.  
  633.  
  634.  
  635. until input$=""
  636.  
  637. endfunction toklist$()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement