cr88192

Idea for a small BASIC-like language.

Oct 25th, 2025
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.16 KB | None | 0 0
  1. Idea: uBASIC / UBAS:
  2. * Core: Small BASIC like language.
  3. * Will assume a combination of global and dynamic scope.
  4. * In simple case, interpreter should be able to be simple.
  5. ** Allowing for a simple interpreter will take precedence over elegance.
  6. ** This language is not intended to be scaled to non-trivial use patterns.
  7.  
  8. The language will be mostly unstructured, but will use GOSUB/RETURN to manage a dynamic environment. This environment will function like a stack, with new GOSUBs pushing levels, and RETURN poping levels. Variable lookup will start in the current frame and search outwards.
  9.  
  10. In the simple case, the interpreter can be understood as starting at the top of the program and stepping one line at a time.
  11.  
  12. Expression evaluation may be token driven, with an intermediate working stack.
  13. * The stack used for expression evaluation need not exist between expressions.
  14. * Operators may also be pushed to a stack, and applied after the subexpression.
  15.  
  16. Will assume the use of a dynamic type system.
  17. * May optionally support JS like objects.
  18. * They will have keys/values, but no methods.
  19. ** Methods would add more implementation complexity than is justified here.
  20.  
  21. Note that it is likely the language will be extended with new keywords based on context.
  22.  
  23.  
  24. === Token Rules ===
  25.  
  26. Text Format:
  27. * May assume a sort of Lazy UTF-8.
  28. ** Presume that the code follows UTF-8.
  29. ** However, implementation need only deal with ASCII in code.
  30. ** Limit the scope of extended characters to string literals and comments.
  31.  
  32. Line Continuations:
  33. * If a line ends in a '\' token:
  34. ** The following line will append to the current line.
  35. * This will be true if followed by a linebreak or line comment.
  36. ** The line comment will be cut off before appending the next line.
  37.  
  38. Comments:
  39. * Will nominally use C style '//' comments
  40. * Note that '//' will not be a comment if inside of a string literal.
  41. * Comments and line continuations may be handled prior to tokenization.
  42. ** A state machnie may be used to avoid the string-literal issue.
  43.  
  44. Name:
  45. * Begins with 'A'..'Z', 'a'..'z', or '_'
  46. * Contains any of the preceding, or '0'..'9'
  47.  
  48. String:
  49. * Wrapped in double qoutes.
  50. * Will use C style escape sequences.
  51. ** \\, \r, \n, \t, \b, \e, \xXX, \uXXXX
  52.  
  53. Character String:
  54. * Wrapped in single quotes.
  55. * Results in an integer value.
  56. * Interpreted as a literal character or multiple characters.
  57. * If multiple characters, value will be understood as a little endian number.
  58.  
  59. Numbers:
  60. * If purely '0'..'9', interpret as decimal.
  61. * Prefix '0x': Interpret as Hexadecimal
  62. * Prefix '0b': Interpret as Binary
  63. * Prefix '0o': Interpret as Octal
  64.  
  65. Operators:
  66. * Will be understood as one or more operator characters.
  67. ** Any combination of operator characters are understood as an operator.
  68. ** Terminated by a non-operator character.
  69. ** The behavior of invalid operators is undefined.
  70. * Operators: ~ ! # % ^ & * - + = | < / > ?
  71.  
  72. Separators:
  73. * Will represent separator characters.
  74. * Unlike operators, separators will not merge.
  75. * Separators: , ; . ( ) [ ] { }
  76.  
  77. An implementation may or may not be case sensitive.
  78. * However, keywords may be written as either upper or lower case.
  79. ** An implementation will not be required to support mixed-case keywords.
  80.  
  81.  
  82.  
  83. === Core Statements ===
  84.  
  85. Core language:
  86. * name ':' //Label
  87. * name '=' expr //Assign a variable
  88. * GOTO name //Transfer a control-flow to a label
  89. * GOSUB name //Like GOTO, but also create a local frame
  90. ** GOSUB name varslist //GOSUB but with arguments
  91. *** Each argument will take the form: name '=' expr
  92. *** They will bound within the callee scope.
  93. * RETURN //Control returns from a GOSUB
  94. * RETURN expr //RETURN with expression (return value).
  95. * LET name '=' expr //Bind a variable
  96. * IF expr THEN stmt //If expression is true, run statement
  97. * IF expr THEN stmt ELSE stmt //IF/ELSE
  98. * IF expr GOTO name //If expression is true, GOTO name
  99. * END //Terminate the current execution context
  100. ** Toplevel: Terminate execution.
  101. ** GOSUB: May be interpreted as RETURN
  102.  
  103. Compounds:
  104. * X = GOSUB* //GOSUB with return value.
  105. * LET X = GOSUB* //GOSUB with return value (LET).
  106. * name '[' index ']' '=' expr //Array assignment
  107. * name '.' name '=' expr //Member assignment
  108. * DIM name '[' size ']'
  109.  
  110. The behavior of LET will depend on context:
  111. * Not inside a GOSUB: Will bind a global variable.
  112. * Inside a GOSUB: Will bind within the dynamic environment.
  113. * LET will not create a binding if the name already exists in the same frame.
  114.  
  115. If a return value is expected but not provided by callee, it will be understood as a NULL value.
  116.  
  117. Note that an assignment statement will not be required to support an arbitrary expression on the LHS.
  118.  
  119. Aliases:
  120. * CALL name //Alias for GOSUB
  121. ** CALL may be allowed in most cases where GOSUB is allowed.
  122.  
  123.  
  124. === Structured Constructs (Optional) ===
  125.  
  126. If the implementation wants to allow structured constructs, some may be defined.
  127. * These will be optional as they are more complicated for a line interpreter.
  128.  
  129. Subroutine/Function:
  130. SUB name [ '(' argslist ')' ]
  131. ...
  132. END
  133.  
  134. If an argument list is provided, it will give names to use for any positional arguments for a CALL. Positional arguments will always precede named arguments.
  135.  
  136.  
  137. Block If:
  138. IF expr THEN
  139. ...
  140. END
  141.  
  142. Block If/Else:
  143. IF expr THEN
  144. ...
  145. ELSE
  146. ...
  147. END
  148.  
  149. While Loop:
  150. WHILE cond
  151. ...
  152. END
  153.  
  154. Do/While:
  155. DO
  156. ...
  157. WHILE cond
  158.  
  159. For-In Loop:
  160. FOR i = start TO end [ STEP step ]
  161. ...
  162. END | NEXT
  163.  
  164.  
  165. === Non-Core Statements ===
  166.  
  167. These will be statements that depend on the implementation or context.
  168.  
  169. Will define several:
  170. * PRINT exprlist //Print one or more expressions.
  171. * INPUT promptString ',' name //request an input from user
  172.  
  173. In some cases, the use of built-in functions will be replaced with builtin subroutines, such as:
  174. Y = GOSUB SQRT X
  175.  
  176.  
  177. === Expressions ===
  178.  
  179. Expressions:
  180. * Will be organized into precedence levels.
  181. * exprLit:
  182. ** name, number, string
  183. ** '(' expr ')' //expression in parenthesis
  184. ** '(' GOSUB * ')' //GOSUB with return (contextual)
  185. ** '[' exprlist ']' //Creates an array given a list of expressions.
  186. *** May only be allowed in certain contexts.
  187. * name '[' index ']' //Array access
  188. * name '.' name //Member Access
  189. * name '(' exprlist ')' //Function Call (optional)
  190. ** Need only be supported if inline function calls are supported.
  191. ** May impose similar restrictions to GOSUB expressions.
  192. * '(' DIM name '[' size ']' ')' //create an array of a given size.
  193. * '{' keyvalList '}' //Creates an object (optional).
  194.  
  195. * exprUnary:
  196. ** exprLit
  197. ** '-' exprUnary
  198. ** '!' exprUnary
  199. ** '~' exprUnary
  200.  
  201. * exprMulDiv:
  202. ** exprUnary
  203. ** exprMulDiv '*' exprUnary
  204. ** exprMulDiv '/' exprUnary
  205. ** exprMulDiv '%' exprUnary
  206.  
  207. * exprAddSub:
  208. ** exprMulDiv
  209. ** exprAddSub '+' exprMulDiv
  210. ** exprAddSub '-' exprMulDiv
  211.  
  212. * exprShift:
  213. ** exprAddSub
  214. ** exprShift '<<' exprAddSub
  215. ** exprShift '>>' exprAddSub
  216.  
  217. * exprCmp:
  218. ** exprShift
  219. ** exprCmp cmpOp exprShift
  220. *** cmpOp: One of: < > <= >= == !=
  221.  
  222.  
  223. === Types ===
  224.  
  225. Values will by dynamically typed.
  226. * Nominally, may assume the use of 64-bit tagrefs.
  227.  
  228. Some value types will be defined:
  229. * Integer: Values up to 62 bits (sign extended).
  230. * Float: Double precision numbers, may lose several bits of mantissa.
  231. * Object: May represent various objects, implementation specific.
  232. ** Array: Array of values (dynamically typed, one dimensional)
  233. ** String: Holds the value of a string, array like, immutable.
  234. *** If accessed as an array, a string will be seen as UTF-8 bytes.
  235. *** It will be illegal to assign a character within a string.
  236.  
  237. If an expression is used as a conditional, it will be understood as:
  238. * Integer: 0 is False, all other values are True.
  239. * Float: All values other than 0.0 and NaN are True.
  240. * Object: NULL is False, everything else is True.
  241. * Array: Always True.
  242.  
  243. Comparisons:
  244. * '==': True if types are equal and values are equal. Otherwise false.
  245. * '!=': Direct logical inverse of '=='.
  246. * Relative Compare: Need only compare between compatible types.
  247. ** Will always return false for incompatible types.
  248. ** Both Integer and Float values may be compared with each other.
  249. ** Relative compare will be undefined for Object types.
  250.  
Tags: basic
Advertisement
Add Comment
Please, Sign In to add comment