time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

parse.js (3125B)


      1 import * as Result from "../utility/result.js";
      2 import { ICompileError } from "../errors/IError.js";
      3 import { SyntaxError as PeggySyntaxError, parse as peggyParse, } from "./peggyParser.js";
      4 export function parse(expr, source) {
      5     try {
      6         const comments = [];
      7         const parsed = peggyParse(expr, {
      8             grammarSource: source,
      9             comments,
     10         });
     11         if (parsed.type !== "Program") {
     12             throw new Error("Expected parse to result in a Program node");
     13         }
     14         parsed.comments = comments;
     15         return Result.Ok(parsed);
     16     }
     17     catch (e) {
     18         if (e instanceof PeggySyntaxError) {
     19             return Result.Err(new ICompileError(e.message, e.location));
     20         }
     21         else {
     22             throw e;
     23         }
     24     }
     25 }
     26 function nodeToString(node) {
     27     const sExpr = (components) => "(" +
     28         node.type +
     29         (components.length ? " " : "") +
     30         components
     31             .map((component) => typeof component === "string" ? component : nodeToString(component))
     32             .join(" ") +
     33         ")";
     34     switch (node.type) {
     35         case "Block":
     36         case "Program":
     37             return sExpr(node.statements);
     38         case "Array":
     39             return sExpr(node.elements);
     40         case "Dict":
     41             return sExpr(node.elements);
     42         case "Boolean":
     43             return String(node.value);
     44         case "Call":
     45             return sExpr([node.fn, ...node.args]);
     46         case "InfixCall":
     47             return sExpr([node.op, ...node.args]);
     48         case "Pipe":
     49             return sExpr([node.leftArg, node.fn, ...node.rightArgs]);
     50         case "DotLookup":
     51             return sExpr([node.arg, node.key]);
     52         case "BracketLookup":
     53             return sExpr([node.arg, node.key]);
     54         case "UnaryCall":
     55             return sExpr([node.op, node.arg]);
     56         case "Float":
     57             return `${node.integer}${node.fractional === null ? "" : `.${node.fractional}`}${node.exponent === null ? "" : `e${node.exponent}`}`;
     58         case "Identifier":
     59             return `:${node.value}`;
     60         case "IdentifierWithAnnotation":
     61             return sExpr([node.variable, node.annotation]);
     62         case "KeyValue":
     63             return sExpr([node.key, node.value]);
     64         case "Lambda":
     65             return sExpr([...node.args, node.body]);
     66         case "LetStatement":
     67             return node.exported
     68                 ? sExpr(["export", node.variable, node.value])
     69                 : sExpr([node.variable, node.value]);
     70         case "DefunStatement":
     71             return sExpr([node.variable, node.value]);
     72         case "String":
     73             return `'${node.value}'`;
     74         case "Ternary":
     75             return sExpr([node.condition, node.trueExpression, node.falseExpression]);
     76         case "Void":
     77             return "()";
     78         case "UnitValue":
     79             return sExpr([node.value, node.unit]);
     80         default:
     81             throw new Error(`Unknown node: ${node}`);
     82     }
     83 }
     84 export function nodeResultToString(r) {
     85     if (!r.ok) {
     86         return r.value.toString();
     87     }
     88     return nodeToString(r.value);
     89 }
     90 //# sourceMappingURL=parse.js.map