lego11

Untitled

Aug 25th, 2014
408
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.94 KB | None | 0 0
  1. term.clear()
  2.  
  3.  
  4. local expr
  5.  
  6. local spacechars = " \t\n\r"
  7.  
  8. local function skipspaces()
  9. while spacechars:find(expr:sub(1, 1),1,true) ~= nil and expr:len() > 0 do
  10. expr = expr:sub(2)
  11. end
  12. end
  13.  
  14. local function acceptch(ch)
  15. skipspaces()
  16. if expr:sub(1,1) == ch then
  17. expr = expr:sub(2)
  18. return true
  19. else
  20. return false
  21. end
  22. end
  23.  
  24. local function acceptnum()
  25. skipspaces()
  26. -- I'm sure there's a better way
  27. for len = expr:len(), 1, -1 do
  28. local success, n = pcall(tonumber, expr:sub(1, len))
  29. if success and n ~= nil then
  30. expr = expr:sub(len + 1)
  31. return n
  32. end
  33. end
  34. return nil
  35. end
  36.  
  37. local alpha = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
  38. local alnum = alpha .. "0123456789"
  39.  
  40. local function acceptident()
  41. local n = 0
  42. skipspaces()
  43. if alpha:find(expr:sub(1, 1),1,true) == nil then return nil end
  44. while alnum:find(expr:sub(n+1, n+1),1,true) ~= nil and expr:len() > n do
  45. n = n + 1
  46. end
  47. local ident = expr:sub(1, n)
  48. expr = expr:sub(n+1)
  49. return ident
  50. end
  51.  
  52. local function parse_error(s)
  53. error(s and ("parse error: " .. s) or "parse error")
  54. end
  55.  
  56. local expression_root
  57.  
  58. local math_functions = {
  59. abs = math.abs,
  60. acos = math.acos,
  61. asin = math.asin,
  62. atan = math.atan,
  63. atan2 = math.atan2,
  64. ceil = math.ceil,
  65. floor = math.floor,
  66. cos = math.cos,
  67. sin = math.sin,
  68. tan = math.tan,
  69. cosh = math.cosh,
  70. sinh = math.sinh,
  71. tanh = math.tanh,
  72. -- math.deg, math.rad
  73. exp = math.exp,
  74. ln = math.log,
  75. log = math.log10,
  76. pow = math.pow,
  77. min = math.min,
  78. max = math.max,
  79. sqrt = math.sqrt,
  80. random = math.random
  81. }
  82.  
  83. local math_constants = {
  84. pi = math.pi,
  85. e = math.exp(1),
  86. inf = math.huge,
  87. nan = math.huge - math.huge
  88. }
  89.  
  90. local function call_function(id, arglist)
  91. if math_functions[id] == nil then
  92. error("no such function: " .. id)
  93. end
  94. return math_functions[id](unpack(arglist))
  95. end
  96.  
  97. local function get_constant(id)
  98. return math_constants[id] or error("no such constant: "..id)
  99. end
  100.  
  101. local function num_or_brackets()
  102. if acceptch("(") then
  103. local n = expression_root()
  104. if not acceptch(")") then parse_error("non-matching parentheses") end
  105. return n
  106. elseif acceptch("-") then
  107. return -expression_root()
  108. else
  109. local id = acceptident()
  110. if id ~= nil then
  111. if not acceptch("(") then
  112. return get_constant(id)
  113. elseif acceptch(")") then
  114. return call_function(id, {})
  115. else
  116. local arglist = {}
  117. local done = false
  118. while not done do
  119. table.insert(arglist, expression_root())
  120. if acceptch(")") then
  121. done = true
  122. elseif not acceptch(",") then
  123. parse_error("expected , or )")
  124. end
  125. end
  126. return call_function(id, arglist)
  127. end
  128. else
  129. local n = acceptnum()
  130. if n == nil then parse_error("expected number or bracketed expression") end
  131. return n
  132. end
  133. end
  134. end
  135.  
  136. local function division()
  137. local n1 = num_or_brackets()
  138. while acceptch("/") do
  139. n1 = n1 / num_or_brackets()
  140. end
  141. return n1
  142. end
  143.  
  144. local function multiplication()
  145. local n1 = division()
  146. while acceptch("*") do
  147. n1 = n1 * division()
  148. end
  149. return n1
  150. end
  151. local function subtraction()
  152. local n1 = multiplication()
  153. while acceptch("-") do
  154. n1 = n1 - multiplication()
  155. end
  156. return n1
  157. end
  158. local function addition()
  159. local n1 = subtraction()
  160. while acceptch("+") do
  161. n1 = n1 + subtraction()
  162. end
  163. return n1
  164. end
  165. expression_root = addition
  166.  
  167. local function parse(e)
  168. expr = e
  169. local success, result = pcall(expression_root)
  170. if success and expr ~= "" then
  171. print("Garbage after expression?")
  172. end
  173. if success then
  174. print("Answer: " .. tostring(result))
  175. else
  176. print(result)
  177. print("Near: " .. (expr == "" and "end of expression" or expr))
  178. end
  179. end
  180.  
  181. local function mainloop()
  182. local quitting = false
  183. print("")
  184. print("Welcome to Aperture Calc")
  185. print("This software is COPYRIGHT (C) 1970 Aperture Laboratories.")
  186. print("REDISTRIBUTION UNDER ANY FORM IS STRICTLY FORBIDDEN")
  187. print("")
  188. print("Enter expressions, one per line.")
  189. print("Enter 'quit' to quit.")
  190. print("")
  191. while not quitting do
  192. local line = io.read()
  193. if line == "quit" then
  194. quitting = true
  195. else
  196. parse(line)
  197. print("")
  198. end
  199. end
  200. end
  201.  
  202. mainloop()
Advertisement
Add Comment
Please, Sign In to add comment