mimo-lang 1.1.1 → 2.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/.gitattributes +24 -0
  2. package/LICENSE +21 -0
  3. package/README.md +71 -39
  4. package/adapters/browserAdapter.js +86 -0
  5. package/adapters/nodeAdapter.js +101 -0
  6. package/bin/cli.js +80 -0
  7. package/bin/commands/convert.js +27 -0
  8. package/bin/commands/doctor.js +139 -0
  9. package/bin/commands/eval.js +39 -0
  10. package/bin/commands/fmt.js +109 -0
  11. package/bin/commands/help.js +72 -0
  12. package/bin/commands/lint.js +117 -0
  13. package/bin/commands/repl.js +24 -0
  14. package/bin/commands/run.js +64 -0
  15. package/bin/commands/test.js +126 -0
  16. package/bin/utils/colors.js +38 -0
  17. package/bin/utils/formatError.js +47 -0
  18. package/bin/utils/fs.js +57 -0
  19. package/bin/utils/version.js +8 -0
  20. package/build.js +18 -0
  21. package/bun.lock +74 -0
  22. package/index.js +48 -77
  23. package/index.web.js +364 -0
  24. package/interpreter/BuiltinFunction.js +32 -0
  25. package/interpreter/ErrorHandler.js +120 -0
  26. package/interpreter/ExpressionEvaluator.js +106 -0
  27. package/interpreter/Interpreter.js +172 -0
  28. package/interpreter/MimoError.js +112 -0
  29. package/interpreter/ModuleLoader.js +236 -0
  30. package/interpreter/StatementExecutor.js +107 -0
  31. package/interpreter/Utils.js +82 -0
  32. package/interpreter/Values.js +87 -0
  33. package/interpreter/coreBuiltins.js +490 -0
  34. package/interpreter/environment.js +99 -0
  35. package/interpreter/evaluators/binaryExpressionEvaluator.js +111 -0
  36. package/interpreter/evaluators/collectionEvaluator.js +151 -0
  37. package/interpreter/evaluators/functionCallEvaluator.js +76 -0
  38. package/interpreter/evaluators/literalEvaluator.js +27 -0
  39. package/interpreter/evaluators/moduleAccessEvaluator.js +25 -0
  40. package/interpreter/evaluators/templateLiteralEvaluator.js +20 -0
  41. package/interpreter/executors/BaseExecutor.js +37 -0
  42. package/interpreter/executors/ControlFlowExecutor.js +206 -0
  43. package/interpreter/executors/FunctionExecutor.js +126 -0
  44. package/interpreter/executors/PatternMatchExecutor.js +93 -0
  45. package/interpreter/executors/VariableExecutor.js +144 -0
  46. package/interpreter/index.js +8 -0
  47. package/interpreter/stdlib/array/accessFunctions.js +61 -0
  48. package/interpreter/stdlib/array/arrayUtils.js +36 -0
  49. package/interpreter/stdlib/array/higherOrderFunctions.js +285 -0
  50. package/interpreter/stdlib/array/searchFunctions.js +77 -0
  51. package/interpreter/stdlib/array/setFunctions.js +49 -0
  52. package/interpreter/stdlib/array/transformationFunctions.js +68 -0
  53. package/interpreter/stdlib/array.js +85 -0
  54. package/interpreter/stdlib/assert.js +143 -0
  55. package/interpreter/stdlib/datetime.js +170 -0
  56. package/interpreter/stdlib/env.js +54 -0
  57. package/interpreter/stdlib/fs.js +161 -0
  58. package/interpreter/stdlib/http.js +92 -0
  59. package/interpreter/stdlib/json.js +70 -0
  60. package/interpreter/stdlib/math.js +309 -0
  61. package/interpreter/stdlib/object.js +142 -0
  62. package/interpreter/stdlib/path.js +69 -0
  63. package/interpreter/stdlib/regex.js +134 -0
  64. package/interpreter/stdlib/string.js +260 -0
  65. package/interpreter/suggestions.js +46 -0
  66. package/lexer/Lexer.js +245 -0
  67. package/lexer/TokenTypes.js +131 -0
  68. package/lexer/createToken.js +11 -0
  69. package/lexer/tokenizers/commentTokenizer.js +45 -0
  70. package/lexer/tokenizers/literalTokenizer.js +163 -0
  71. package/lexer/tokenizers/symbolTokenizer.js +69 -0
  72. package/lexer/tokenizers/whitespaceTokenizer.js +36 -0
  73. package/package.json +29 -13
  74. package/parser/ASTNodes.js +448 -0
  75. package/parser/Parser.js +188 -0
  76. package/parser/expressions/atomicExpressions.js +165 -0
  77. package/parser/expressions/conditionalExpressions.js +0 -0
  78. package/parser/expressions/operatorExpressions.js +79 -0
  79. package/parser/expressions/primaryExpressions.js +77 -0
  80. package/parser/parseStatement.js +184 -0
  81. package/parser/parserExpressions.js +115 -0
  82. package/parser/parserUtils.js +19 -0
  83. package/parser/statements/controlFlowParsers.js +106 -0
  84. package/parser/statements/functionParsers.js +314 -0
  85. package/parser/statements/moduleParsers.js +57 -0
  86. package/parser/statements/patternMatchParsers.js +124 -0
  87. package/parser/statements/variableParsers.js +155 -0
  88. package/repl.js +325 -0
  89. package/test.js +47 -0
  90. package/tools/PrettyPrinter.js +3 -0
  91. package/tools/convert/Args.js +46 -0
  92. package/tools/convert/Registry.js +91 -0
  93. package/tools/convert/Transpiler.js +78 -0
  94. package/tools/convert/plugins/README.md +66 -0
  95. package/tools/convert/plugins/alya/index.js +10 -0
  96. package/tools/convert/plugins/alya/to_alya.js +289 -0
  97. package/tools/convert/plugins/alya/visitors/expressions.js +257 -0
  98. package/tools/convert/plugins/alya/visitors/statements.js +403 -0
  99. package/tools/convert/plugins/base_converter.js +228 -0
  100. package/tools/convert/plugins/javascript/index.js +10 -0
  101. package/tools/convert/plugins/javascript/mimo_runtime.js +265 -0
  102. package/tools/convert/plugins/javascript/to_js.js +155 -0
  103. package/tools/convert/plugins/javascript/visitors/expressions.js +197 -0
  104. package/tools/convert/plugins/javascript/visitors/patterns.js +102 -0
  105. package/tools/convert/plugins/javascript/visitors/statements.js +236 -0
  106. package/tools/convert/plugins/python/index.js +10 -0
  107. package/tools/convert/plugins/python/mimo_runtime.py +811 -0
  108. package/tools/convert/plugins/python/to_py.js +329 -0
  109. package/tools/convert/plugins/python/visitors/expressions.js +272 -0
  110. package/tools/convert/plugins/python/visitors/patterns.js +100 -0
  111. package/tools/convert/plugins/python/visitors/statements.js +257 -0
  112. package/tools/convert.js +102 -0
  113. package/tools/format/CommentAttacher.js +190 -0
  114. package/tools/format/CommentLexer.js +152 -0
  115. package/tools/format/Printer.js +849 -0
  116. package/tools/format/config.js +107 -0
  117. package/tools/formatter.js +169 -0
  118. package/tools/lint/Linter.js +391 -0
  119. package/tools/lint/config.js +114 -0
  120. package/tools/lint/rules/consistent-return.js +62 -0
  121. package/tools/lint/rules/max-depth.js +56 -0
  122. package/tools/lint/rules/no-empty-function.js +45 -0
  123. package/tools/lint/rules/no-magic-numbers.js +46 -0
  124. package/tools/lint/rules/no-shadow.js +113 -0
  125. package/tools/lint/rules/no-unused-vars.js +26 -0
  126. package/tools/lint/rules/prefer-const.js +19 -0
  127. package/tools/linter.js +261 -0
  128. package/tools/replFormatter.js +93 -0
  129. package/tools/stamp-version.js +32 -0
  130. package/web/index.js +9 -0
  131. package/bun.lockb +0 -0
  132. package/cli.js +0 -84
  133. package/compiler/execute/interpreter.js +0 -68
  134. package/compiler/execute/interpreters/binary.js +0 -12
  135. package/compiler/execute/interpreters/call.js +0 -10
  136. package/compiler/execute/interpreters/if.js +0 -10
  137. package/compiler/execute/interpreters/try-catch.js +0 -10
  138. package/compiler/execute/interpreters/while.js +0 -8
  139. package/compiler/execute/utils/createfunction.js +0 -11
  140. package/compiler/execute/utils/evaluate.js +0 -20
  141. package/compiler/execute/utils/operate.js +0 -23
  142. package/compiler/lexer/processToken.js +0 -40
  143. package/compiler/lexer/tokenTypes.js +0 -4
  144. package/compiler/lexer/tokenizer.js +0 -74
  145. package/compiler/parser/expression/comparison.js +0 -18
  146. package/compiler/parser/expression/identifier.js +0 -29
  147. package/compiler/parser/expression/number.js +0 -10
  148. package/compiler/parser/expression/operator.js +0 -21
  149. package/compiler/parser/expression/punctuation.js +0 -31
  150. package/compiler/parser/expression/string.js +0 -6
  151. package/compiler/parser/parseExpression.js +0 -27
  152. package/compiler/parser/parseStatement.js +0 -34
  153. package/compiler/parser/parser.js +0 -45
  154. package/compiler/parser/statement/call.js +0 -26
  155. package/compiler/parser/statement/function.js +0 -29
  156. package/compiler/parser/statement/if.js +0 -34
  157. package/compiler/parser/statement/return.js +0 -10
  158. package/compiler/parser/statement/set.js +0 -11
  159. package/compiler/parser/statement/show.js +0 -10
  160. package/compiler/parser/statement/try-catch.js +0 -25
  161. package/compiler/parser/statement/while.js +0 -22
  162. package/converter/go/convert.js +0 -110
  163. package/converter/js/convert.js +0 -107
  164. package/jsconfig.json +0 -27
  165. package/vite.config.js +0 -17
@@ -1,40 +0,0 @@
1
- // processToken.js
2
-
3
- import { OPERATORS } from "./tokenTypes.js";
4
-
5
- export const isOperator = (char) => OPERATORS.includes(char);
6
-
7
- export const processToken = (currentToken, currentType, tokens) => {
8
- if (currentToken) {
9
- tokens.push({ type: currentType, value: currentToken });
10
- return { currentToken: "", currentType: null };
11
- }
12
- return { currentToken, currentType };
13
- };
14
-
15
- export const processStringToken = (inString, currentToken, tokens) => {
16
- inString = !inString;
17
- if (!inString) {
18
- tokens.push({ type: "string", value: currentToken });
19
- currentToken = "";
20
- }
21
- return { inString, currentToken };
22
- };
23
-
24
- export const processOperatorToken = (char, index, input, currentType, currentToken, tokens) => {
25
- if (currentToken) {
26
- ({ currentToken, currentType } = processToken(currentToken, currentType, tokens));
27
- }
28
-
29
-
30
- currentType = "operator";
31
- currentToken += char;
32
-
33
-
34
- if (index < input.length - 1 && isOperator(input[index + 1])) {
35
- currentToken += input[index + 1];
36
- index++; // Skip the next operator character
37
- }
38
- tokens.push({ type: currentType, value: currentToken });
39
- return { currentToken: "", currentType: null, i:index };
40
- };
@@ -1,4 +0,0 @@
1
- // tokenTypes.js
2
- export const OPERATORS = ["+", "-", "*", "/", ">", "<", "=", "!"];
3
- export const KEYWORDS = ["let", "const", "if", "else", "for", "while", "function", "return"];
4
- export const PUNCTUATION = ["(", ")", ",", "[", "]"];
@@ -1,74 +0,0 @@
1
- import { processToken, processStringToken, processOperatorToken, isOperator } from './processToken.js';
2
- import { PUNCTUATION } from './tokenTypes.js';
3
-
4
- /**
5
- * @typedef {Object} Token
6
- * @property {string} type - The type of the token (e.g., 'number', 'identifier', 'operator', etc.).
7
- * @property {string} value - The value of the token (e.g., '42', 'x', '+', etc.).
8
- */
9
-
10
- /**
11
- * Generate tokens from the given input.
12
- * @param {string} input - The input to be tokenized.
13
- * @returns {Token[]} An array of tokens.
14
- */
15
- function generateTokens(input) {
16
- const tokens = [];
17
- let currentToken = "";
18
- let currentType = null;
19
- let inComment = false;
20
- let inString = false;
21
-
22
- for (let i = 0; i < input.length; i++) {
23
- const char = input[i];
24
-
25
- if (inComment) {
26
- if (char === "\n") {
27
- inComment = false;
28
- }
29
- continue;
30
- }
31
-
32
- if (char === "/" && input[i + 1] === "/") {
33
- inComment = true;
34
- i++; // Skip the second '/'
35
- continue;
36
- }
37
-
38
- if (char === '"') {
39
- ({ inString, currentToken } = processStringToken(inString, currentToken, tokens));
40
- continue;
41
- }
42
-
43
- if (inString) {
44
- currentToken += char;
45
- continue;
46
- }
47
-
48
- if (/\s/.test(char)) {
49
- ({ currentToken, currentType } = processToken(currentToken, currentType, tokens));
50
- continue;
51
- }
52
-
53
- if (isOperator(char)) {
54
- ({ currentToken, currentType, i } = processOperatorToken(char, i, input, currentType, currentToken, tokens));
55
- }else if (PUNCTUATION.includes(char)) {
56
- ({ currentToken, currentType } = processToken(currentToken, currentType, tokens));
57
- tokens.push({ type: "punctuation", value: char });
58
- } else {
59
- currentToken += char;
60
- if (!currentType) {
61
- currentType = /[a-zA-Z]/.test(char)
62
- ? "identifier"
63
- : /[0-9]/.test(char)
64
- ? "number"
65
- : null;
66
- }
67
- }
68
- }
69
-
70
- ({ currentToken, currentType } = processToken(currentToken, currentType, tokens));
71
- return tokens;
72
- }
73
-
74
- export { generateTokens };
@@ -1,18 +0,0 @@
1
- import { parseExpression } from "../parseExpression.js";
2
-
3
- export function comparisonExpression(tokens, index) {
4
- const operator = tokens[index++].value;
5
- let left = parseExpression(tokens, index);
6
- index = left.index; // Update the index
7
- let right = parseExpression(tokens, index);
8
- index = right.index; // Update the index
9
- return {
10
- expression: {
11
- type: "comparison",
12
- operator,
13
- left: left.expression,
14
- right: right.expression,
15
- },
16
- index,
17
- };
18
- }
@@ -1,29 +0,0 @@
1
- import { parseExpression } from "../parseExpression.js";
2
-
3
- export function identifierExpression(tokens, index) {
4
- if (
5
- tokens[index + 1]?.value === "[" &&
6
- tokens[index + 3]?.value === "]"
7
- ) {
8
- const name = tokens[index].value;
9
- index += 2; // Skip identifier and '['
10
- const indexExpression = parseExpression(tokens, index);
11
- index = indexExpression.index; // Update the index
12
- if (tokens[index]?.value === "]") {
13
- index++; // Skip ']'
14
- }
15
- return {
16
- expression: {
17
- type: "indexAccess",
18
- name,
19
- index: indexExpression.expression,
20
- },
21
- index,
22
- };
23
- } else {
24
- return {
25
- expression: { type: "variable", name: tokens[index++].value },
26
- index,
27
- };
28
- }
29
- }
@@ -1,10 +0,0 @@
1
-
2
- export function numberExpression(tokens, index){
3
- return {
4
- expression: {
5
- type: "literal",
6
- value: parseFloat(tokens[index++].value),
7
- },
8
- index,
9
- };
10
- }
@@ -1,21 +0,0 @@
1
- import { parseExpression } from "../parseExpression.js";
2
-
3
- export function operatorExpression(tokens, index) {
4
- let operator = tokens[index++].value;
5
- let left = parseExpression(tokens, index);
6
- index = left.index; // Update the index
7
- if (tokens[index]?.type === "operator") {
8
- operator += tokens[index++].value; // Handle two-character operators like '=='
9
- }
10
- let right = parseExpression(tokens, index);
11
- index = right.index; // Update the index
12
- return {
13
- expression: {
14
- type: "binary",
15
- operator,
16
- left: left.expression,
17
- right: right.expression,
18
- },
19
- index,
20
- };
21
- }
@@ -1,31 +0,0 @@
1
- import { parseExpression } from "../parseExpression.js";
2
-
3
- export function punctuationExpression(tokens, index) {
4
- if (tokens[index].value === "[") {
5
- index++; // Skip '['
6
- const elements = [];
7
- while (
8
- tokens[index]?.type !== "punctuation" &&
9
- tokens[index]?.value !== "]"
10
- ) {
11
- let result = parseExpression(tokens, index);
12
- elements.push(result.expression);
13
- index = result.index; // Update the index
14
- if (
15
- tokens[index]?.type === "punctuation" &&
16
- tokens[index]?.value === ","
17
- ) {
18
- index++; // Skip ',' between elements
19
- }
20
- }
21
- if (tokens[index]?.value === "]") {
22
- index++; // Skip ']'
23
- }
24
- return { expression: { type: "list", elements }, index };
25
- }
26
-
27
- return {
28
- expression: { type: "punctuation", value: tokens[index++].value },
29
- index,
30
- };
31
- }
@@ -1,6 +0,0 @@
1
- export function stringExpression(tokens, index){
2
- return {
3
- expression: { type: "literal", value: tokens[index++].value },
4
- index,
5
- };
6
- }
@@ -1,27 +0,0 @@
1
- import { comparisonExpression } from "./expression/comparison.js";
2
- import { identifierExpression } from "./expression/identifier.js";
3
- import { numberExpression } from "./expression/number.js";
4
- import { operatorExpression } from "./expression/operator.js";
5
- import { punctuationExpression } from "./expression/punctuation.js";
6
- import { stringExpression } from "./expression/string.js";
7
-
8
- export const parseExpression = (tokens, index) => {
9
- // console.log("expression..", tokens[index].type, tokens[index].value);
10
-
11
- switch (tokens[index].type) {
12
- case "number":
13
- return numberExpression(tokens, index);
14
- case "string":
15
- return stringExpression(tokens, index);
16
- case "identifier":
17
- return identifierExpression(tokens, index);
18
- case "operator":
19
- return operatorExpression(tokens, index);
20
- case "punctuation":
21
- return punctuationExpression(tokens, index);
22
- default:
23
- if (["<", ">", ">=", "<=", "==", "!="].includes(tokens[index].value)) {
24
- return comparisonExpression(tokens, index);
25
- }
26
- }
27
- };
@@ -1,34 +0,0 @@
1
- import { ifStatement } from "./statement/if.js";
2
- import { setStatement } from "./statement/set.js";
3
- import { tryCatchStatement } from "./statement/try-catch.js";
4
- import { whileStatement } from "./statement/while.js";
5
- import { functionStatement } from "./statement/function.js";
6
- import { callStatement } from "./statement/call.js";
7
- import { returnStatement } from "./statement/return.js";
8
- import { showStatement } from "./statement/show.js";
9
-
10
- export const parseStatement = (tokens, index) => {
11
- let statement = { type: "statement" };
12
-
13
- if (tokens[index].value === "set") {
14
- ({ statement, index } = setStatement(tokens, index));
15
- } else if (tokens[index].value === "if") {
16
- ({ statement, index } = ifStatement(tokens, index));
17
- } else if (tokens[index].value === "while") {
18
- ({ statement, index } = whileStatement(tokens, index));
19
- } else if (tokens[index].value === "try") {
20
- ({ statement, index } = tryCatchStatement(tokens, index));
21
- } else if (tokens[index].value === "function") {
22
- ({ statement, index } = functionStatement(tokens, index));
23
- } else if (tokens[index].value === "call") {
24
- ({ statement, index } = callStatement(tokens, index));
25
- } else if (tokens[index].value === "return") {
26
- ({ statement, index } = returnStatement(tokens, index));
27
- } else if (tokens[index].value === "show") {
28
- ({ statement, index } = showStatement(tokens, index));
29
- } else {
30
- index++;
31
- }
32
-
33
- return { statement, index };
34
- };
@@ -1,45 +0,0 @@
1
- import { parseStatement } from "./parseStatement.js";
2
-
3
-
4
- /**
5
- * @typedef {import('../lexer/tokenizer.js').Token} Token
6
- */
7
-
8
- /**
9
- * @typedef {Object} Node
10
- * @property {string} type - The type of the node (e.g., 'binary', 'assignment', 'literal', etc.).
11
- * optionals
12
- * @property {string} [operator] - The operator (e.g., '+', '-', '*', '/', etc.).
13
- * @property {Node} [left] - The left node.
14
- * @property {Node} [right] - The right node.
15
- * @property {Node} [condition] - The expression node.
16
- * @property {Node} [consequent] - The consequent node.
17
- * @property {Node} [expression] - The expression node.
18
- * @property {Node} [alternate] - The alternate node.
19
- * @property {string} [target] - The target of the assignment.
20
- * @property {number} [value] - The value to be assigned.
21
- * @property {string} [name] - The name of functions and variables.
22
- * @property {string[]} [params] - The parameters of a function.
23
- * @property {Node[]} [body] - The body of a block statement.
24
- */
25
-
26
- /**
27
- * Parse the list of tokens into an abstract syntax tree (AST).
28
- * @param {Token[]} tokens - The list of tokens to be parsed.
29
- * @returns {Node[]} An array of AST nodes.
30
- */
31
-
32
- export function parseTokens(tokens) {
33
- let index = 0;
34
-
35
- const program = [];
36
- while (index < tokens.length) {
37
- let statement;
38
- let result = parseStatement(tokens, index);
39
- statement = result.statement;
40
- index = result.index; // Update the index
41
- program.push(statement);
42
- }
43
-
44
- return program;
45
- }
@@ -1,26 +0,0 @@
1
- import { parseExpression } from "../parseExpression.js";
2
-
3
- export const callStatement = (tokens, index) => {
4
- let statement = { type: "call" };
5
- statement.name = tokens[index + 1]?.value;
6
- index += 2; // Skip 'call' and function name
7
- statement.args = [];
8
- statement.target = null;
9
- if (tokens[index].value === "(") {
10
- index++; // Skip '('
11
- while (tokens[index].value !== ")") {
12
- if (tokens[index].value !== ",") {
13
- let result = parseExpression(tokens, index);
14
- statement.args.push(result.expression);
15
- index = result.index; // Update the index
16
- } else {
17
- index++; // Skip ','
18
- }
19
- }
20
- index++; // Skip ')'
21
- }
22
- if ((tokens[index++].value = "->")) {
23
- statement.target = tokens[index++].value;
24
- }
25
- return { statement, index };
26
- };
@@ -1,29 +0,0 @@
1
- import { parseStatement } from "../parseStatement.js";
2
-
3
- // #file:statement/function.js
4
- export const functionStatement = (tokens, index) => {
5
- index++; // Skip 'function'
6
- let statement = { type: "function" };
7
- statement.name = tokens[index++]?.value;
8
- index++; // Skip 'function' and function name
9
- statement.params = [];
10
- while (tokens[index] && tokens[index]?.value !== ")") {
11
- statement.params.push(tokens[index]?.value);
12
- index++; // Skip parameter
13
- if (tokens[index]?.value === ",") {
14
- index++; // Skip ','
15
- }
16
- }
17
- index++; // Skip ')'
18
- const body = [];
19
- while (tokens[index] && tokens[index].value !== "endfunction") {
20
- let result = parseStatement(tokens, index);
21
- body.push(result.statement);
22
- index = result.index; // Update the index
23
- }
24
- if (tokens[index] && tokens[index].value === "endfunction") {
25
- index++;
26
- }
27
- statement.body = body;
28
- return { statement, index };
29
- };
@@ -1,34 +0,0 @@
1
- import { parseExpression } from "../parseExpression.js";
2
- import { parseStatement } from "../parseStatement.js";
3
-
4
- export function ifStatement(tokens, index) {
5
- let statement = { type: "if" };
6
- index++;
7
- let result = parseExpression(tokens, index);
8
- statement.condition = result.expression;
9
- index = result.index; // Update the index
10
- statement.consequent = [];
11
-
12
- while (
13
- tokens[index] &&
14
- tokens[index].value !== "endif" &&
15
- tokens[index].value !== "else"
16
- ) {
17
- let result = parseStatement(tokens, index);
18
- statement.consequent.push(result.statement);
19
- index = result.index; // Update the index
20
- }
21
- if (tokens[index].value === "else") {
22
- index++;
23
- statement.alternate = [];
24
- while (tokens[index] && tokens[index].value !== "endif") {
25
- let result = parseStatement(tokens, index);
26
- statement.alternate.push(result.statement);
27
- index = result.index; // Update the index
28
- }
29
- }
30
- if (tokens[index].value === "endif") {
31
- index++;
32
- }
33
- return { statement, index };
34
- }
@@ -1,10 +0,0 @@
1
- import { parseExpression } from "../parseExpression.js";
2
-
3
- // #file:statement/return.js
4
- export const returnStatement = (tokens, index) => {
5
- let statement = { type: "return" };
6
- let result = parseExpression(tokens, index + 1);
7
- statement.expression = result.expression;
8
- index = result.index; // Update the index
9
- return { statement, index };
10
- };
@@ -1,11 +0,0 @@
1
- import { parseExpression } from "../parseExpression.js";
2
-
3
- export function setStatement(tokens, index) {
4
- let statement = { type: "assignment" };
5
- index++;
6
- statement.target = tokens[index++].value;
7
- let result = parseExpression(tokens, index);
8
- statement.value = result.expression;
9
- index = result.index; // Update the index
10
- return { statement, index };
11
- }
@@ -1,10 +0,0 @@
1
- import { parseExpression } from "../parseExpression.js";
2
-
3
- export const showStatement = (tokens, index) => {
4
- let statement = { type: "print" };
5
- index++; // Skip 'show'
6
- let result = parseExpression(tokens, index);
7
- statement.value = result.expression;
8
- index = result.index; // Update the index
9
- return { statement, index };
10
- };
@@ -1,25 +0,0 @@
1
- import { parseStatement } from "../parseStatement.js";
2
-
3
- export const tryCatchStatement = (tokens, index) => {
4
- let statement = { type: "try-catch" };
5
- statement.tryBlock = [];
6
- index++;
7
- while (tokens[index] && tokens[index].value !== "catch") {
8
- let result = parseStatement(tokens, index);
9
- statement.tryBlock.push(result.statement);
10
- index = result.index; // Update the index
11
- }
12
- if (tokens[index].value === "catch") {
13
- index++;
14
- statement.catchBlock = [];
15
- while (tokens[index] && tokens[index].value !== "endtry") {
16
- let result = parseStatement(tokens, index);
17
- statement.catchBlock.push(result.statement);
18
- index = result.index; // Update the index
19
- }
20
- }
21
- if (tokens[index].value === "endtry") {
22
- index++;
23
- }
24
- return { statement, index };
25
- };
@@ -1,22 +0,0 @@
1
- import { parseExpression } from "../parseExpression.js";
2
- import { parseStatement } from "../parseStatement.js";
3
-
4
-
5
- export const whileStatement = (tokens, index) => {
6
- index++; // Skip 'while'
7
- let statement = { type: "while" };
8
- let result = parseExpression(tokens, index);
9
- statement.condition = result.expression;
10
- index = result.index; // Update the index
11
- const body = [];
12
- while (tokens[index] && tokens[index].value !== "endwhile") {
13
- let result = parseStatement(tokens, index);
14
- body.push(result.statement);
15
- index = result.index; // Update the index
16
- }
17
- if (tokens[index].value === "endwhile") {
18
- index++;
19
- }
20
- statement.body = body;
21
- return { statement, index };
22
- };
@@ -1,110 +0,0 @@
1
- let declaredVariables = new Set();
2
-
3
- function generateGoCodeFromAst(node) {
4
- switch (node.type) {
5
- case "function":
6
- return generateFunction(node);
7
- case "assignment":
8
- return generateAssignment(node);
9
- case "while":
10
- return generateWhile(node);
11
- case "if":
12
- return generateIf(node);
13
- case "return":
14
- return generateReturn(node);
15
- case "call":
16
- return generateCall(node);
17
- case "print":
18
- return generatePrint(node);
19
- case "literal":
20
- return node.value;
21
- case "variable":
22
- return node.name;
23
- case "binary":
24
- return generateBinary(node);
25
- default:
26
- throw new Error(`Unknown node type: ${node.type}`);
27
- }
28
- }
29
-
30
- export function generateGoCodeFromAstArray(ast) {
31
- declaredVariables = new Set();
32
- const functionCode = ast
33
- .filter((node) => node.type === "function")
34
- .map(generateGoCodeFromAst)
35
- .join("\n\n");
36
- const otherCode = ast
37
- .filter((node) => node.type !== "function")
38
- .map(generateGoCodeFromAst)
39
- .join("\n");
40
- return formatGoCode(`
41
- package main
42
-
43
- import "fmt"
44
-
45
- ${functionCode}
46
-
47
- func main() {
48
- ${otherCode}
49
- }
50
- `);
51
- }
52
-
53
- function generateFunction(node) {
54
- const params = node.params.map((p) => `${p} any`).join(", ");
55
- const body = node.body.map(generateGoCodeFromAst).join("\n");
56
- return `func ${node.name}(${params}) any {\n${body}\n}`;
57
- }
58
-
59
- function generateAssignment(node) {
60
- let prefix = "";
61
- if (!declaredVariables.has(node.target)) {
62
- prefix = "var ";
63
- declaredVariables.add(node.target);
64
- }
65
- return `${prefix}${node.target} = ${generateGoCodeFromAst(node.value)}`;
66
- }
67
-
68
- function generateWhile(node) {
69
- const condition = generateGoCodeFromAst(node.condition);
70
- const body = node.body.map(generateGoCodeFromAst).join("\n");
71
- return `for ${condition} {\n${body}\n}`;
72
- }
73
-
74
- function generateIf(node) {
75
- const condition = generateGoCodeFromAst(node.condition);
76
- const consequent = node.consequent.map(generateGoCodeFromAst).join("\n");
77
- return `if ${condition} {\n${consequent}\n}`;
78
- }
79
-
80
- function generateReturn(node) {
81
- return `return ${generateGoCodeFromAst(node.expression)}`;
82
- }
83
-
84
- function generateCall(node) {
85
- const args = node.args.map(generateGoCodeFromAst).join(", ");
86
- let callCode = `${node.name}(${args})`;
87
- if (node.target) {
88
- let prefix = "";
89
- if (!declaredVariables.has(node.target)) {
90
- prefix = "var ";
91
- declaredVariables.add(node.target);
92
- }
93
- callCode = `${prefix}${node.target} = ${callCode}`;
94
- }
95
- return callCode;
96
- }
97
-
98
- function generatePrint(node) {
99
- return `fmt.Println(${generateGoCodeFromAst(node.value)})`;
100
- }
101
-
102
- function generateBinary(node) {
103
- const left = generateGoCodeFromAst(node.left);
104
- const right = generateGoCodeFromAst(node.right);
105
- return `${left} ${node.operator} ${right}`;
106
- }
107
-
108
- function formatGoCode(code) {
109
- return code;
110
- }