minigrace
Version:
A compiler for the Grace programming language
902 lines • 245 kB
JavaScript
let gracecode_errormessages_sourceFile = "/Users/black/Development/mg/gracelang/minigrace/errormessages.grace";
let gracecode_errormessages_sha256 = "1223563f7ff475e1e86364e246ad522efabc5397ccee40261f36f88564d77bb9";
let gracecode_errormessages_minigraceRevision = "b57591d29fc5ee5270d114920bf671367b8c3ecb";
let gracecode_errormessages_minigraceGeneration = "5171";
if (typeof gctCache !== "undefined")
gctCache["errormessages"] = "dialect:\n standard\nfreshScopes:\n $104\n $105\n $107\n $108\nmethodTypes:$102:\n ambiguityError(defs:Unknown)node(node:Unknown) \u2192 None\n name(p:String)matches(t:String)within(d:Number) \u2192 Unknown\n name(p:String)mightBeIntendedToBe(target:String) \u2192 Unknown\n readableStringFrom(xs:Collection)using(connectingWord:String) \u2192 Unknown\n syntaxError(message:String, errLinenum:Number, errPosition:String, arr:String, suggestions:Collection) \u2192 Unknown\nmodules:\n basic\n io\n standard\n sys\n util\npath:\n /Users/black/Development/mg/gracelang/minigrace/errormessages.grace\nscope:$102:\n AstNode type\n CompilationError Unknown (def) $scope_done public\n CompilerError Unknown (mth) $scope_done\n GatheringError Unknown (mth) $scope_done\n NamingError Unknown (def) $scope_done public\n Position type\n Range type\n ReuseError Unknown (def) $scope_done public\n Scope type\n SyntaxError Unknown (def) $scope_done public\n Variable type\n ambiguityError(1)node(1) None (mth) $scope_done\n asDebugString String (go) $scope_string\n asString String (go) $scope_string\n badAssignmentTo(1)declaredInScope(1) Unknown (mth) $scope_done\n basicAsString String (go) $scope_string\n canonicalName(1) Unknown (mth) $scope_done\n emptyRange Unknown (mth) $scope_done\n error(1) Unknown (mth) $scope_done\n error(1)atLine(1) Unknown (mth) $scope_done\n error(1)atLine(1)withSuggestions(1) Unknown (mth) $scope_done\n error(1)atPosition(2) Unknown (mth) $scope_done\n error(1)atPosition(2)withSuggestions(1) Unknown (mth) $scope_done\n error(1)atRange(1) Unknown (mth) $scope_done\n error(1)atRange(3) Unknown (mth) $scope_done\n error(1)atRange(3)withSuggestions(1) Unknown (mth) $scope_done\n error(1)atRange(4)withSuggestions(1) Unknown (mth) $scope_done\n fakeSymbolTable Unknown (mth) $104\n guessesForIdentifier(1) Unknown (mth) $scope_done\n isMe(1) Boolean (go) $scope_boolean\n line(1)column(1) Position (mth) $105\n min3(3) Unknown (mth) $scope_done confidential\n myIdentityHash Number (go) $scope_number\n name(1)matches(1)within(1) Unknown (mth) $scope_done\n name(1)mightBeIntendedToBe(1) Unknown (mth) $scope_done\n namingError(1) Unknown (mth) $scope_done\n namingError(1)atRange(1) Unknown (mth) $scope_done\n noPosition Unknown (mth) $scope_done\n nullNode AstNode (mth) $106\n numericName(1) Unknown (mth) $scope_done\n readableStringFrom(1) Unknown (mth) $scope_done\n readableStringFrom(1)using(1) Unknown (mth) $scope_done\n reuseError(1) Unknown (mth) $scope_done\n reuseError(1)atRange(1) Unknown (mth) $scope_done\n start(1)end(1) Range (mth) $107\n suggestion Unknown (def) $103 public\n syntaxError(1)atLine(1) Unknown (mth) $scope_done\n syntaxError(1)atLine(1)withSuggestion(1) Unknown (mth) $scope_done\n syntaxError(1)atLine(1)withSuggestions(1) Unknown (mth) $scope_done\n syntaxError(1)atPosition(2) Unknown (mth) $scope_done\n syntaxError(1)atPosition(2)withSuggestion(1) Unknown (mth) $scope_done\n syntaxError(1)atPosition(2)withSuggestions(1) Unknown (mth) $scope_done\n syntaxError(1)atRange(1) Unknown (mth) $scope_done\n syntaxError(1)atRange(1)withSuggestion(1) Unknown (mth) $scope_done\n syntaxError(1)atRange(1)withSuggestions(1) Unknown (mth) $scope_done\n syntaxError(1)atRange(3) Unknown (mth) $scope_done\n syntaxError(1)atRange(3)withSuggestion(1) Unknown (mth) $scope_done\n syntaxError(1)atRange(3)withSuggestions(1) Unknown (mth) $scope_done\n syntaxError(1)atRange(4) Unknown (mth) $scope_done\n syntaxError(1)atRange(4)withSuggestions(1) Unknown (mth) $scope_done\n syntaxError(5) Unknown (mth) $scope_done\n undeclaredIdentifier(1) Unknown (mth) $scope_done\nscope:$103:\n asDebugString String (go) $scope_string\n asString String (go) $scope_string\n basicAsString String (go) $scope_string\n isMe(1) Boolean (go) $scope_boolean\n myIdentityHash Number (go) $scope_number\n new Unknown (mth) $108\nscope:$104:\n ::(1) Unknown (mth) $scope_done\n ==(1) Unknown (mth) $scope_done\n areReusedNamesCompleted Unknown (mth) $scope_done\n asDebugString String (go) $scope_string\n asString Unknown (mth) $scope_done\n basicAsString String (go) $scope_string\n hash Unknown (mth) $scope_done\n isFresh Unknown (mth) $scope_done\n isMe(1) Boolean (go) $scope_boolean\n localNames Unknown (mth) $scope_done\n myIdentityHash Number (go) $scope_number\n node Unknown (var) $scopeEmpty\n node:=(1) Unknown (var) $scopeEmpty\n prefix== Unknown (mth) $scope_done\n prefix\u2260 Unknown (mth) $scope_done\n variety Unknown (mth) $scope_done\n varsAreMethods Unknown (mth) $scope_done\n \u2260(1) Unknown (mth) $scope_done\nscope:$105:\n ::(1) Unknown (mth) $scope_done\n <(1) Boolean (mth) $scope_done\n ==(1) Boolean (mth) $scope_done\n >(1) Boolean (mth) $scope_done\n addColumn(1) Unknown (mth) $scope_done\n addLine(1) Unknown (mth) $scope_done\n asDebugString String (go) $scope_string\n asString Unknown (mth) $scope_done\n basicAsString String (go) $scope_string\n column Unknown (def) $scopeEmpty\n hash Number (mth) $scope_done\n isMe(1) Boolean (go) $scope_boolean\n line Unknown (def) $scopeEmpty\n myIdentityHash Number (go) $scope_number\n prefix== Unknown (mth) $scope_done\n prefix\u2260 Unknown (mth) $scope_done\n \u2260(1) Unknown (mth) $scope_done\n \u2264(1) Boolean (mth) $scope_done\n \u2265(1) Boolean (mth) $scope_done\nscope:$106:\n ::(1) Unknown (mth) $scope_done\n ==(1) Unknown (mth) $scope_done\n accept(1)from(1) Unknown (mth) $scope_done\n annotations Unknown (mth) $scope_done\n asDebugString String (go) $scope_string\n asString Unknown (mth) $scope_done\n basicAsString String (go) $scope_string\n childrenDo(1) Unknown (mth) $scope_done\n childrenMap(1) Unknown (mth) $scope_done\n column Unknown (def) $scope_number\n column:=(1) Unknown (mth) $scope_done\n comments Unknown (mth) $scope_done\n decType Unknown (mth) $scope_done\n end Position (mth) $scope_done\n endCol Unknown (mth) $scope_done\n hasAnnotation(1) Unknown (mth) $scope_done\n hash Unknown (mth) $scope_done\n inClass Unknown (mth) $scope_done\n inTrait Unknown (mth) $scope_done\n isAssignment Unknown (mth) $scope_done\n isBlock Unknown (mth) $scope_done\n isBuiltIn Unknown (mth) $scope_done\n isCall Unknown (mth) $scope_done\n isClass Unknown (mth) $scope_done\n isComment Unknown (mth) $scope_done\n isConstant Unknown (mth) $scope_done\n isDeclaredByParent Unknown (mth) $scope_done\n isDialect Unknown (mth) $scope_done\n isExecutable Unknown (mth) $scope_done\n isExternal Unknown (mth) $scope_done\n isFresh Unknown (mth) $scope_done\n isIdentifier Unknown (mth) $scope_done\n isImport Unknown (mth) $scope_done\n isMarkerDeclaration Unknown (mth) $scope_done\n isMe(1) Boolean (go) $scope_boolean\n isMember Unknown (mth) $scope_done\n isMethod Unknown (mth) $scope_done\n isModule Unknown (mth) $scope_done\n isNull Unknown (mth) $scope_done\n isObject Unknown (mth) $scope_done\n isOuter Unknown (mth) $scope_done\n isReturn Unknown (mth) $scope_done\n isSelf Unknown (mth) $scope_done\n isSelfOrOuter Unknown (mth) $scope_done\n isSequenceConstructor Unknown (mth) $scope_done\n isSuper Unknown (mth) $scope_done\n isTrait Unknown (mth) $scope_done\n isTypeDec Unknown (mth) $scope_done\n kind Unknown (def) $scope_string\n line Unknown (def) $scope_number\n line:=(1) Unknown (mth) $scope_done\n map(1)ancestors(1) Unknown (mth) $scope_done\n myIdentityHash Number (go) $scope_number\n nameString Unknown (mth) $scope_done\n newAccept(1) Unknown (mth) $scope_done\n prefix== Unknown (mth) $scope_done\n prefix\u2260 Unknown (mth) $scope_done\n pretty(1) Unknown (mth) $scope_done\n range Unknown (mth) $scope_done\n register Unknown (def) $scope_string\n scope Unknown (def) $104\n shallowCopy Unknown (mth) $scope_done\n start Unknown (mth) $scope_done\n toGrace(1) Unknown (mth) $scope_done\n \u2260(1) Unknown (mth) $scope_done\nscope:$107:\n ::(1) Unknown (mth) $scope_done\n <(1) Unknown (mth) $scope_done\n ==(1) Unknown (mth) $scope_done\n >(1) Unknown (mth) $scope_done\n arrow Unknown (mth) $scope_done\n asDebugString String (go) $scope_string\n asString Unknown (mth) $scope_done\n basicAsString String (go) $scope_string\n column Unknown (mth) $scope_done\n end Unknown (def) $scopeEmpty\n hash Number (mth) $scope_done\n isMe(1) Boolean (go) $scope_boolean\n line Unknown (mth) $scope_done\n lineRangeString Unknown (mth) $scope_done\n myIdentityHash Number (go) $scope_number\n prefix== Unknown (mth) $scope_done\n prefix\u2260 Unknown (mth) $scope_done\n rangeLongString Unknown (mth) $scope_done\n rangeString Unknown (mth) $scope_done\n start Unknown (def) $scopeEmpty\n sugg Unknown (mth) $scope_done\n \u2260(1) Unknown (mth) $scope_done\n \u2264(1) Unknown (mth) $scope_done\n \u2265(1) Unknown (mth) $scope_done\nscope:$108:\n ::(1) Unknown (mth) $scope_done\n ==(1) Unknown (mth) $scope_done\n addLine(2) Unknown (mth) $scope_done\n append(1)onLine(1) Unknown (mth) $scope_done\n asDebugString String (go) $scope_string\n asString String (go) $scope_string\n basicAsString String (go) $scope_string\n deleteChar(1)onLine(1) Unknown (mth) $scope_done\n deleteLine(1) Unknown (mth) $scope_done\n deleteRange(2)onLine(1) Unknown (mth) $scope_done\n deleteToken(1) Unknown (mth) $scope_done\n deleteToken(1)leading(1)trailing(1) Unknown (mth) $scope_done\n deleteTokenRange(2) Unknown (mth) $scope_done\n deleteTokenRange(2)leading(1)trailing(1) Unknown (mth) $scope_done\n findLine(1) Unknown (mth) $scope_done confidential\n getLine(1) Unknown (mth) $scope_done confidential\n getTokenEnd(1)includeTrailingSpace(1) Unknown (mth) $scope_done\n getTokenStart(1)includeLeadingSpace(1) Unknown (mth) $scope_done\n hash Unknown (mth) $scope_done\n insert(1)afterToken(1) Unknown (mth) $scope_done\n insert(1)afterToken(1)andTrailingSpace(1) Unknown (mth) $scope_done\n insert(1)atPosition(1)onLine(1) Unknown (mth) $scope_done\n insert(1)beforeToken(1) Unknown (mth) $scope_done\n insertNewLine(1)after(1) Unknown (mth) $scope_done\n isMe(1) Boolean (go) $scope_boolean\n lineNumbers Unknown (def) $scopeUniv public\n lines Unknown (def) $scopeUniv public\n myIdentityHash Number (go) $scope_number\n prefix== Unknown (mth) $scope_done\n prefix\u2260 Unknown (mth) $scope_done\n print Unknown (mth) $scope_done\n replaceChar(1)with(1)onLine(1) Unknown (mth) $scope_done\n replaceRange(2)with(1)onLine(1) Unknown (mth) $scope_done\n replaceToken(1)leading(1)trailing(1)with(1) Unknown (mth) $scope_done\n replaceToken(1)with(1) Unknown (mth) $scope_done\n replaceTokenRange(2)leading(1)trailing(1)with(1) Unknown (mth) $scope_done\n replaceTokenRange(2)with(1) Unknown (mth) $scope_done\n replaceUntil(1)with(1)onLine(1) Unknown (mth) $scope_done\n \u2260(1) Unknown (mth) $scope_done\nself:\n $102\ntypes:\n";
if (typeof originalSourceLines !== "undefined") {
originalSourceLines["errormessages"] = [
"dialect \"standard\"",
"import \"io\" as io",
"import \"sys\" as sys",
"import \"util\" as util",
"import \"basic\" as basic",
"",
"use basic.open",
"",
"def suggestion is public = object {",
" // Contains modified lines used as suggestions for error messages.",
" // When a line is added using one of the utility methods such as",
" // insert()afterToken()onLine(), the line is copied from util.lines to the",
" // lines array in the suggestion. When a line that is already in",
" // the array is modified, the lines array is updated.",
" // There is no sorting of the order of the lines at any point, so",
" // lines must be added in ascending order.",
"",
" class new {",
" use equality",
"",
" def lineNumbers is public = list.empty // two parallel arrays,",
" def lines is public = list.empty // simulating a dictionary",
"",
" method ==(other) {",
" if (lineNumbers == other.lineNumbers) then {",
" if (lines == other.lines) then { return true }",
" }",
" return false",
" }",
"",
" method hash { lines.hash }",
"",
" // Methods that deal with inserting/replacing/deleting character positions",
" // and ranges. These methods are usually called by lexing error messages",
" // due to lack of access to tokens, and by insert/replace/delete methods",
" // that operate on tokens.",
"",
" method replaceRange(start, end)with(s)onLine(lineNumber) {",
" def line = getLine(lineNumber)",
" def size = line.size",
" if (size == 0) then {",
" addLine(lineNumber, s)",
" } else {",
" def newStart = min(start, size)",
" def newEnd = min(end, size)",
" addLine(lineNumber, line.substringFrom 1 to (newStart - 1)",
" ++ s ++ line.substringFrom (newEnd + 1))",
" }",
" }",
"",
" method replaceChar(pos)with(s)onLine(lineNumber) {",
" replaceRange(pos, pos)with(s)onLine(lineNumber)",
" }",
"",
" method replaceUntil(until)with(s)onLine(lineNumber) {",
" def line = getLine(lineNumber)",
" def len = until.size",
" for (1..line.size) do {i->",
" if (line.substringFrom(i)to(i + len - 1) == until) then {",
" replaceRange(1, i + len - 1)with(s)onLine(lineNumber)",
" return true",
" }",
" }",
" return false",
" }",
"",
" method deleteRange(start, end)onLine(lineNumber) {",
" var start' := start",
" def line = getLine(lineNumber)",
" if ((start > 1) && (end == line.size) && (start ≤ end)) then {",
" // Check for removing the whole line, then remove the indent also.",
" var indent := true",
" for(1..(start'-1)) do { i ->",
" if(line.at(i) != \" \") then {",
" indent := false",
" }",
" }",
" if(indent == true) then {",
" start' := 1",
" }",
" }",
" replaceRange(start', end)with(\"\")onLine(lineNumber)",
" }",
"",
" method deleteChar(pos)onLine(lineNumber) {",
" replaceRange(pos, pos)with(\"\")onLine(lineNumber)",
" }",
"",
" method append(s)onLine(lineNumber) {",
" def line = getLine(lineNumber)",
" addLine(lineNumber, line ++ s)",
" }",
"",
" method insert(s)atPosition(pos)onLine(lineNumber) {",
" def line = getLine(lineNumber)",
" if (pos > line.size) then {",
" addLine(lineNumber, line ++ s)",
" } else {",
" addLine(lineNumber, line.substringFrom(1)to(pos - 1) ++ s",
" ++ line.substringFrom(pos)to(line.size))",
" }",
" }",
"",
" // Methods that deal with inserting/replacing/deleteing tokens or ranges of",
" // tokens. These methods call the underlying methods that operate on",
" // characters.",
"",
" method getTokenStart(token)includeLeadingSpace(includeLeading) {",
" var start := token.column",
" // Include leading whitespace.",
" if (true == includeLeading) then {",
" if (token.hasPrev && {token.prev.line == token.line}) then {",
" start := token.prev.column + token.prev.size",
" }",
" }",
" // Include indentation if this is the only token on the line.",
" if (token.column == (token.indent + 1)) then {",
" if (token.hasNext.not || {token.next.line ≠ token.line}) then {",
" start := 1",
" }",
" }",
" start",
" }",
"",
" method getTokenEnd(token)includeTrailingSpace(includeTrailing) {",
" var end := token.column + token.size - 1",
" // Include trailing space.",
" if (true == includeTrailing) then {",
" if (token.hasNext && {token.next.line == token.line}) then {",
" end := token.next.column - 1",
" } else {",
" end := getLine(token.line).size",
" }",
" }",
" end",
" }",
"",
" method replaceToken(token)leading(replaceLeading)trailing(replaceTrailing)with(s) {",
" def start = getTokenStart(token)includeLeadingSpace(replaceLeading)",
" def end = getTokenEnd(token)includeTrailingSpace(replaceTrailing)",
" replaceRange(start, end)with(s)onLine(token.line)",
" }",
"",
" method replaceToken(token)with(s) {",
" replaceToken(token)leading(false)trailing(false)with(s)",
" }",
"",
" method replaceTokenRange(start, end)leading(replaceLeading)trailing(replaceTrailing)with(s) {",
" if(start == end) then {",
" replaceToken(start)leading(replaceLeading)trailing(replaceTrailing)with(s)",
" } else {",
" // Get the ident and position now in case deleteTokenRange changes it.",
" def insertPos = getTokenStart(start)includeLeadingSpace(replaceLeading)",
" def indent = getLine(start.line).substringFrom(1)to(start.indent)",
" deleteTokenRange(start, end)leading(replaceLeading)trailing(replaceTrailing)",
" // If delete token range deleted the indent, then add it back.",
" if(getLine(start.line) == \"\") then {",
" insert(indent ++ s)atPosition(insertPos)onLine(start.line)",
" } else {",
" insert(s)atPosition(insertPos)onLine(start.line)",
" }",
" }",
" }",
"",
" method replaceTokenRange(start, end)with(s) {",
" replaceTokenRange(start, end)leading(false)trailing(false)with(s)",
" }",
"",
" // Deletes a token, and optionally leading and/or trailing spaces.",
" method deleteToken(token)leading(deleteLeading)trailing(deleteTrailing) {",
" def start = getTokenStart(token)includeLeadingSpace(deleteLeading)",
" def end = getTokenEnd(token)includeTrailingSpace(deleteTrailing)",
" deleteRange(start, end)onLine(token.line)",
" }",
"",
" method deleteToken(token) {",
" deleteToken(token)leading(false)trailing(false)",
" }",
"",
" // Deletes a range of tokens, and optionally leading and/or trailing spaces.",
" method deleteTokenRange(start, end)leading(deleteLeading)trailing(deleteTrailing) {",
" if(start == end) then {",
" deleteToken(start)leading(deleteLeading)trailing(deleteTrailing)",
" } else {",
" var line := start.line",
" var startPos := getTokenStart(start)includeLeadingSpace(deleteLeading)",
" var endPos := getTokenEnd(start)includeTrailingSpace(deleteTrailing)",
" var tok := start.next",
" while {tok != end} do {",
" if(tok.line != line) then {",
" deleteRange(startPos, endPos)onLine(line)",
" line := tok.line",
" startPos := getTokenStart(tok)includeLeadingSpace(deleteLeading)",
" }",
" endPos := getTokenEnd(tok)includeTrailingSpace(deleteTrailing)",
" tok := tok.next",
" }",
" if(end.line != line) then {",
" deleteRange(startPos, endPos)onLine(line)",
" }",
" endPos := getTokenEnd(end)includeTrailingSpace(deleteTrailing)",
" deleteRange(startPos, endPos)onLine(end.line)",
" }",
" }",
"",
" method deleteTokenRange(start, end) {",
" deleteTokenRange(start, end)leading(false)trailing(false)",
" }",
"",
" method deleteLine(lineNumber) {",
" addLine(lineNumber, \"\")",
" }",
"",
" method insert(s)afterToken(token)andTrailingSpace(afterTrailing) {",
" def pos = getTokenEnd(token)includeTrailingSpace(afterTrailing) + 1",
" insert(s)atPosition(pos)onLine(token.line)",
" }",
"",
" method insert(s)afterToken(token) {",
" insert(s)afterToken(token)andTrailingSpace(false)",
" }",
"",
" method insert(s)beforeToken(token) {",
" insert(s)atPosition(token.column)onLine(token.line)",
" }",
"",
" // Insert a new line. This stores the line with the same number as the line it comes after.",
" method insertNewLine(line)after(lineNumber) {",
" addLine(lineNumber, line)",
" }",
"",
" // Manually add a line to the suggestion. This will overwrite any previous",
" // changes that may have been made to this line.",
" method addLine(lineNumber, line) {",
" var i := findLine(lineNumber)",
" if(i != false) then {",
" lines.at(i)put(line)",
" } else {",
" // Add new lines to make the list big enough.",
" lineNumbers.push(lineNumber)",
" lines.push(line)",
" if (lines.size > 1) then {",
" // Re-order the list.",
" i := lines.size",
" while {(i > 1) && {lineNumber < lineNumbers.at(i - 1)}} do {",
" lineNumbers.at(i) put(lineNumbers.at(i - 1))",
" lines.at(i) put (lines.at(i - 1))",
" i := i - 1",
" }",
" lineNumbers.at(i) put (lineNumber)",
" lines.at(i) put (line)",
" }",
" }",
" }",
"",
" // Internal method used to find the index of a line in the lines array.",
" // Returns false if the line is not found.",
" method findLine(lineNumber) is confidential {",
" for(lineNumbers.indices) do { i ->",
" if(lineNumbers.at(i) == lineNumber) then {",
" return i",
" }",
" }",
" false",
" }",
"",
" // Internal method used to get the contents of a line so far.",
" // If the line is not part of this suggestion then it gets the unmodified line.",
" method getLine(lineNumber) is confidential {",
" def i = findLine(lineNumber)",
" if(i == false) then {",
" util.lines.at(lineNumber)",
" } else {",
" lines.at(i)",
" }",
" }",
"",
" method print {",
" for(1..lines.size) do { i ->",
" if ((i > 1) && {(lineNumbers.at(i) > (lineNumbers.at(i-1) + 1))}) then {",
" var s := \"\"",
" repeat (lineNumbers.at(i-1).asString.size) times {",
" s := s ++ \" \"",
" }",
" io.error.write(\" {s}...\\n\")",
" }",
" // Handle insertion of new lines.",
" if(lineNumbers.at(i).truncated != lineNumbers.at(i)) then {",
" io.error.write(\" *{lineNumbers.at(i).truncated}: {lines.at(i)}\\n\")",
" } else {",
" io.error.write(\" {lineNumbers.at(i)}: {lines.at(i)}\\n\")",
" }",
" }",
" }",
" }",
"}",
"",
"method readableStringFrom(xs:Collection) using (connectingWord:String) {",
" // returns a string describing the contents of xs,",
" // separating items with commas and the word \"and\"",
" var result := \"\"",
" var count := xs.size",
" xs.do { v ->",
" result := result ++ v.asString",
" count := count - 1",
" if (count == 1) then {",
" if (xs.size > 2) then { result := result ++ \",\" }",
" result := result ++ \" \" ++ connectingWord ++ \" \"",
" } elseif { count > 1 } then {",
" result := result ++ \", \"",
" }",
" }",
" result",
"}",
"",
"method readableStringFrom(xs) {",
" readableStringFrom(xs) using \"and\"",
"}",
"",
"method name (p:String) mightBeIntendedToBe (target:String) {",
" // heuristics for finding typos, mis-spellings, etc.",
"",
" if (p.contains \"$\") then { return false }",
" if (p.startsWithLetter ≠ target.startsWithLetter) then { return false }",
" // either both operators, or both names",
" def parenIx = p.indexOf \"(\" ifAbsent { p.size + 1 }",
" def pPrefix = p.substringFrom 1 to (parenIx - 1)",
" if (target.startsWith(pPrefix)) then { return true }",
" if (target.size > (p.size * 2)) then { return false }",
" def rng = name (p) matches (target) within 2",
" if (rng == 0) then { return false }",
" if (rng > (p.size * 2)) then { return false } // found too far along",
" return true",
"}",
"",
"",
"method name (p:String) matches (t:String) within (d:Number) {",
" // This is algorithm EDP from Jokinen, Jorma, Tarhio and Ukkinen:",
" // \"A comparison of Approximate String Matching Algorithms\"",
" // Software—Practice and Experience Vol 1(1), January 1988, pp.1–19",
" //",
" // Implements the \"Enhanced Dynamic Programming\" (EDP) algorithm for",
" // approximate string matching. If pattern p matches text t within",
" // an edit distance ≤ d, this method returns j, the index of the highest",
" // character of t involved in the match. Its time compelxity is O(d*|p|).",
" //",
" // The algorithm builds a dynamic progarmming table D such that",
" // D[i,j] is the minimum edit distance between p[1] p[2] ... p[i]",
" // and any substring of t ending at t[j]. However, it isn't necessary",
" // to store the whole table D. Because D[i,j] depends on only D[i-1, j],",
" // D[i-1, j-1] and D[i, j-1], we can store only the current",
" // column, which we do in h, and the value of D[i-1,j-1], which is",
" // cached in c. Moreover, since we are not interested in edit",
" // distances > d, it's necessary to evaluate only those elements",
" // of the table around the diagonal.",
"",
"",
" def m = p.size",
" def n = t.size",
" if ((m ≤ d)) then {",
" return min(m, n) // can match first min(m, n) chars of t",
" }",
" var top := d + 1 // the location where the topmost diagonal under",
" // threshold intersects the current column",
" var maxResult := 0",
" def h = list.empty",
" for (0..m) do { i -> h.at(i+1) put(i) }",
" try {",
" for (1..n) do { j ->",
" var c := 0",
" for (1..top) do { i ->",
" def e = if (p.at(i) == t.at(j)) then {",
" c",
" } else {",
" min3(h.at(i), h.at(i+1), c) + 1",
" }",
" c := h.at(i+1)",
" h.at(i+1) put (e)",
" }",
" while { h.at(top+1) > d } do { top := top - 1 }",
" if (top == m) then {",
" maxResult := max(maxResult, j) // j is the index of",
" // the last character of t that was used in the match",
" } else {",
" top := top + 1",
" }",
" }",
" } catch { e:BoundsError ->",
" print \"BoundsError in name({p})matches({t})within({d})\"",
" e.printBacktrace",
" return 0 } // if the code is buggy, don't crash",
" return maxResult",
"}",
"",
"method min3(a, b, c) is confidential {",
" def sf = if (a < b) then { a } else { b }",
" if (sf < c) then { sf } else { c }",
"}",
"",
"// Methods to raise a SyntaxError exception, with an accompanying",
"// data object that contains information and suggestions.",
"// The exception will normally be caught by a try(_)catch(_) in",
"// the compiler module, which requests util.generalError to",
"// actually print the message",
"",
"def CompilationError is public = Exception.refine \"CompilationError\"",
"def SyntaxError is public = CompilationError.refine \"SyntaxError\"",
"def ReuseError is public = CompilationError.refine \"ReuseError\"",
"def NamingError is public = CompilationError.refine \"NamingError\"",
"",
"method syntaxError(message:String, errLinenum:Number,",
" errPosition:String, arr:String, suggestions:Collection) {",
" // Used by various wrapper methods declared below.",
" // The parameters mean:",
" // - message: The text of the error message.",
" // - errLinenum: The line number on which the error occurred.",
" // - errPosition: A string used to show the position of the error in the error message.",
" // - arr: The string used to draw an arrow showing the position of the error.",
" // - suggestions: A (possibly empty) list of suggestions to correct the error.",
"",
" def errorObj = object {",
" def line is public = errLinenum",
" def column is public = errPosition",
" def arrow is public = arr",
" def sugg is public = suggestions",
" }",
" SyntaxError.raise (message) with (errorObj)",
"}",
"",
"method syntaxError (message) atRange (r) {",
" def more = if ((r.start.line < r.end.line) && {",
" util.lines.at(r.start.line).endsWith \"\\{\" .not",
" }) then {",
" \" This statement spans multiple lines; is that what you intended?\"",
" } else {",
" \"\"",
" }",
" syntaxError (message ++ more) atRange (r) withSuggestions []",
"}",
"method syntaxError (message) atRange (r) withSuggestion (s) {",
" syntaxError (message) atRange (r) withSuggestions [s]",
"}",
"method syntaxError (message) atRange (r) withSuggestions (s) {",
" syntaxError (message)",
" atRange (r.start.line, r.start.column, r.end.line, r.end.column)",
" withSuggestions (s)",
"}",
"",
"method syntaxError(message)atRange(errLinenum, startpos, endpos) {",
" syntaxError(message)atRange(errLinenum, startpos, endpos)withSuggestions []",
"}",
"",
"method syntaxError (message) atRange (sl, sp, el, ep) {",
" syntaxError (message) atRange (sl, sp, el, ep) withSuggestions []",
"}",
"",
"method syntaxError(message) atRange(errLinenum, startpos, endpos) withSuggestion(suggestion') {",
" syntaxError(message) atRange(errLinenum, startpos, endpos) withSuggestions [suggestion']",
"}",
"",
"method syntaxError(message) atRange(errLinenum, startpos, endpos) withSuggestions(suggestions) {",
" syntaxError (message)",
" atRange (errLinenum, startpos, errLinenum, endpos)",
" withSuggestions (suggestions)",
"}",
"",
"method syntaxError (message)",
" atRange (startline, startpos, endline, endpos)",
" withSuggestions (suggestions) {",
"",
" // this variant allows for range to start and end on different lines.",
" def loc = if (startline == endline) then {",
" if (startpos == endpos)",
" then { startpos.asString }",
" else { \"{startpos}-{endpos}\" }",
" } else { \"{startpos}-{endline}:{endpos}\" }",
" def arr = (\"-\" * (startpos-1)) ++ (\"^\" * (endpos - startpos + 1))",
" syntaxError(message, startline, \"{loc}\", arr, suggestions)",
"}",
"",
"method namingError (message) atRange (r) {",
" NamingError.raise (message) with (r)",
"}",
"",
"method namingError (message) {",
" NamingError.raise (message)",
"}",
"",
"method reuseError (message) atRange (r) {",
" ReuseError.raise (message) with (r)",
"}",
"",
"method reuseError (message) {",
" ReuseError.raise (message)",
"}",
"",
"method error (message) atRange (r) {",
" error (message)",
" atRange (r.start.line, r.start.column, r.end.line, r.end.column)",
" withSuggestions []",
"}",
"",
"method error (message)",
" atRange (startline, startpos, endline, endpos)",
" withSuggestions (suggestions) {",
"",
" // this variant allows for range to start and end on different lines.",
" def loc = if (startline == endline) then {",
" if (startpos == endpos)",
" then { startpos.asString }",
" else { \"{startpos}-{endpos}\" }",
" } else { \"{startpos}-{endline}:{endpos}\" }",
" def arr = (\"-\" * (startpos-1)) ++ (\"^\" * (endpos - startpos + 1))",
" def errorObj = object {",
" def line is public = startline",
" def column is public = loc",
" def arrow is public = arr",
" def sugg is public = suggestions",
" }",
" CompilationError.raise(message) with (errorObj)",
"}",
"",
"method error(message) atRange(errLinenum, startpos, endpos) withSuggestions(suggestions) {",
" error (message)",
" atRange (errLinenum, startpos, errLinenum, endpos)",
" withSuggestions (suggestions)",
"}",
"",
"method error(message) atRange(errLinenum, startpos, endpos) {",
" error (message) atRange(errLinenum, startpos, endpos) withSuggestions []",
"}",
"",
"method syntaxError(message) atPosition(errLinenum, errpos) {",
" syntaxError(message)atPosition(errLinenum, errpos)withSuggestions []",
"}",
"",
"method error(message) atPosition(errLinenum, errpos) {",
" error(message) atPosition(errLinenum, errpos) withSuggestions []",
"}",
"",
"method syntaxError(message) atPosition(errLinenum, errpos) withSuggestion(suggestion') {",
" syntaxError(message) atPosition(errLinenum, errpos) withSuggestions [suggestion']",
"}",
"",
"method syntaxError(message)atPosition(errLinenum, errpos)withSuggestions(suggestions) {",
" def arr = (\"-\" * (errpos-1)) ++ \"^\"",
" syntaxError(message, errLinenum, \"{errpos}\", arr, suggestions)",
"}",
"",
"",
"method ambiguityError (defs) node (node) → None {",
" // Signals an ambiguity error. Does not return",
"",
" var msg := \"the name `{node.canonicalName}` is ambiguous; it might refer to either the \"",
" defs.do { aVar →",
" msg := msg ++ aVar.resolutionString",
" } separatedBy {",
" msg := msg ++ \", or the \"",
" }",
" syntaxError (msg) atRange (node.range)",
"}",
"",
"method undeclaredIdentifier(node) {",
" def guesses = guessesForIdentifier(node)",
" def cn = node.canonicalName",
" def varBit = if (cn.endsWith \")\") then { \"\" } else { \" variable or\" }",
" def guessBit = if (guesses.isEmpty) then {",
" \"\"",
" } else {",
" \". Did you mean {readableStringFrom(guesses) using \"or\"}?\"",
" }",
" syntaxError(\"unknown{varBit} method '{cn}'; \" ++",
" \"this may be a spelling mistake, or an attempt to access a{varBit} \" ++",
" \"method in another scope{guessBit}\")",
" atRange (node.range)",
"}",
"",
"",
"method error(message) atPosition(errLinenum, errPosition)",
" withSuggestions(suggestions) {",
" def arr = \"^\"",
"",
" def errorObj = object {",
" def line is public = errLinenum",
" def column is public = errPosition",
" def arrow is public = arr",
" def sugg is public = suggestions",
" }",
" CompilationError.raise (message) with (errorObj)",
"}",
"",
"method guessesForIdentifier(node) {",
" def nm = node.nameString",
" def guesses = set.empty",
" def nodeScope = node.scope",
" def thresh = 4 // max number of guesses",
" try {",
" nodeScope.withSurroundingScopesDo { s →",
" s.localAndReusedNamesAndValuesDo { n, _ →",
" if (name (nm) mightBeIntendedToBe(n)) then {",
" guesses.add(canonicalName(n))",
" if (guesses.size ≥ thresh) then { return guesses }",
" }",
" }",
" }",
" nodeScope.localAndReusedNamesAndValuesDo { n, v →",
" if (v.attributeScope.defines(nm)) then {",
" guesses.add \"{n}.{canonicalName(nm)}\"",
" if (guesses.size ≥ thresh) then { return guesses }",
" }",
" }",
" } catch { ex:GatheringError -> }",
" guesses",
"}",
"",
"method badAssignmentTo(node) declaredInScope(scp) {",
" // Report a syntax error for an illegal assignment",
"",
" def name = node.canonicalName",
" def variable = scp.lookupLocallyOrReused(name)",
" def lineInfo = if (variable.range.start.line == 0) then {",
" \"\"",
" } else {",
" \" on {variable.lineRangeString}\"",
" }",
" if ( variable.kind == \"def\" ) then {",
" syntaxError(\"'{name}' cannot be changed \" ++",
" \"because it was declared with 'def'{lineInfo}. To make it \" ++",
" \"a variable, use 'var {name}' and ':=' in the declaration\")",
" atRange(node.range)",
" } elseif { variable.kind == \"import\" } then {",
" syntaxError(\"'{name}' cannot be changed \" ++",
" \"because it was declared with 'import'{lineInfo}.\")",
" atRange(node.range)",
" } elseif { variable.kind == \"type\" } then {",
" syntaxError(\"'{name}' cannot be re-bound \" ++",
" \"because it is declared as a type{lineInfo}.\")",
" atRange(node.range)",
" } elseif { variable.isParameter } then {",
" syntaxError(\"'{name}' cannot be re-bound \" ++",
" \"because it is declared as a parameter{lineInfo}.\")",
" atRange(node.range)",
" } elseif { variable.kind == \"methodDec\" } then {",
" syntaxError(\"'{name}' cannot be re-bound \" ++",
" \"because it is declared as a method{lineInfo}.\")",
" atRange(node.range)",
" }",
"}",
"",
"method error(message) {",
" error(message) atPosition(0, \"\") withSuggestions []",
"}",
"",
"method error(message) atLine(errLinenum) withSuggestions(suggestions) {",
" def arr = if ((errLinenum > 0) && (errLinenum <= util.lines.size)) then {",
" \"^\" * util.lines.at(errLinenum).size",
" } else {",
" \"^\"",
" }",
" def errorObj = object {",
" def line is public = errLinenum",
" def column is public = \"\"",
" def arrow is public = arr",
" def sugg is public = suggestions",
" }",
" CompilationError.raise (message) with (errorObj)",
"",
"}",
"",
"method error(message)atLine(errLinenum) {",
" error(message)atLine(errLinenum)withSuggestions []",
"}",
"",
"method syntaxError(message)atLine(errLinenum) {",
" syntaxError(message)atLine(errLinenum)withSuggestions []",
"}",
"",
"method syntaxError(message) atLine(errLinenum) withSuggestion(suggestion') {",
" syntaxError(message) atLine(errLinenum) withSuggestions [suggestion']",
"}",
"",
"method syntaxError(message) atLine(errLinenum) withSuggestions(suggestions) {",
" def arr = \"^\" * util.lines.at(errLinenum).size",
" syntaxError(message, errLinenum, \"\", arr, suggestions)",
"}" ];
}
function gracecode_errormessages() {
importedModules["errormessages"] = this;
const var_$module = this;
this.definitionModule = "errormessages";
this.definitionLine = 1;
setLineNumber(1); // compilenode dialect
// Dialect "standard"
const var_$dialect = do_import("standard", gracecode_standard);
this.outer = var_$dialect;
setLineNumber(2); // compilenode import
// Import of "io" as io
if (typeof gracecode_io == "undefined")
throw new GraceExceptionPacket(EnvironmentExceptionObject,
new GraceString("could not find module io"));
var var_io = do_import("io", gracecode_io);
var func0 = function(argcv) { // accessor method io, line 2
const numArgs = arguments.length - 1;
if (numArgs > 0) raiseTypeArgError("io", 0, numArgs - 0);
return var_io;
}; // end of method io
this.methods["io"] = func0;
func0.methodName = "io";
func0.paramCounts = [0];
func0.paramNames = [];
func0.definitionLine = 2;
func0.definitionModule = "errormessages";
func0.debug = "import";
func0.confidential = true;
setLineNumber(3); // compilenode import
// Import of "sys" as sys
if (typeof gracecode_sys == "undefined")
throw new GraceExceptionPacket(EnvironmentExceptionObject,
new GraceString("could not find module sys"));
var var_sys = do_import("sys", gracecode_sys);
var func1 = function(argcv) { // accessor method sys, line 3
const numArgs = arguments.length - 1;
if (numArgs > 0) raiseTypeArgError("sys", 0, numArgs - 0);
return var_sys;
}; // end of method sys
this.methods["sys"] = func1;
func1.methodName = "sys";
func1.paramCounts = [0];
func1.paramNames = [];
func1.definitionLine = 3;
func1.definitionModule = "errormessages";
func1.debug = "import";
func1.confidential = true;
setLineNumber(4); // compilenode import
// Import of "util" as util
if (typeof gracecode_util == "undefined")
throw new GraceExceptionPacket(EnvironmentExceptionObject,
new GraceString("could not find module util"));
var var_util = do_import("util", gracecode_util);
var func2 = function(argcv) { // accessor method util, line 4
const numArgs = arguments.length - 1;
if (numArgs > 0) raiseTypeArgError("util", 0, numArgs - 0);
return var_util;
}; // end of method util
this.methods["util"] = func2;
func2.methodName = "util";
func2.paramCounts = [0];
func2.paramNames = [];
func2.definitionLine = 4;
func2.definitionModule = "errormessages";
func2.debug = "import";
func2.confidential = true;
setLineNumber(5); // compilenode import
// Import of "basic" as basic
if (typeof gracecode_basic == "undefined")
throw new GraceExceptionPacket(EnvironmentExceptionObject,
new GraceString("could not find module basic"));
var var_basic = do_import("basic", gracecode_basic);
var func3 = function(argcv) { // accessor method basic, line 5
const numArgs = arguments.length - 1;
if (numArgs > 0) raiseTypeArgError("basic", 0, numArgs - 0);
return var_basic;
}; // end of method basic
this.methods["basic"] = func3;
func3.methodName = "basic";
func3.paramCounts = [0];
func3.paramNames = [];
func3.definitionLine = 5;
func3.definitionModule = "errormessages";
func3.debug = "import";
func3.confidential = true;
this.closureKeys = this.closureKeys || [];
this.closureKeys.push("outer_errormessages_1");
this.outer_errormessages_1 = var_$dialect;
setLineNumber(7); // reuse call
var initFun4 = request(var_basic, "open$build(3)", [null], this, [], []); // compileReuseCall
var func5 = function(argcv, var_xs, var_connectingWord) { // method readableStringFrom(_)using(_), line 298
var returnTarget = invocationCount;
invocationCount++;
const numArgs = arguments.length - 1;
if ((numArgs > 2) && (numArgs !== 2)) {
raiseTypeArgError("readableStringFrom(_)using(_)", 0, numArgs - 2);
}
setLineNumber(298); // compilenode member
var call6 = selfRequest(var_$dialect, "Collection", [0]);
assertTypeOrMsg(var_xs, call6, "argument 1 in request of `readableStringFrom(_)using(_)`", "Collection");
var call7 = selfRequest(var_$dialect, "String", [0]);
assertTypeOrMsg(var_connectingWord, call7, "argument 2 in request of `readableStringFrom(_)using(_)`", "String");
setLineNumber(301); // compilenode string
var var_result = GraceEmptyString;
setLineNumber(302); // compilenode member
// call case 4: other requests
var call8 = request(var_xs, "size", [0]);
var var_count = call8;
setLineNumber(303); // compilenode block
var block10 = new GraceBlock(this, 303, 1);
block10.guard = jsTrue;
block10.real = function block10(var_v) {
setLineNumber(304); // compilenode member
// call case 4: other requests
var call12 = request(var_v, "asString", [0]);
// call case 4: other requests
if (var_result === undefined) raiseUninitializedVariable("result");
var concat11 = request(var_result, "++(1)", [1], call12);
var_result = concat11;
setLineNumber(305); // compilenode num
// call case 4: other requests
if (var_count === undefined) raiseUninitializedVariable("count");
var diff13 = request(var_count, "-(1)", [1], new GraceNum(1));
var_count = diff13;
var if14 = GraceDone;
setLineNumber(306); // compilenode num
// call case 4: other requests
if (var_count === undefined) raiseUninitializedVariable("count");
var term15 = request(var_count, "==(1)", [1], new GraceNum(1));
if (Grace_isTrue(term15)) {
var if16 = GraceDone;
setLineNumber(307); // compilenode num
// call case 4: other requests
// call case 4: other requests
var call18 = request(var_xs, "size", [0]);
var term17 = request(call18, ">(1)", [1], new GraceNum(2));
if (Grace_isTrue(term17)) {
var string20 = new GraceString(",");
// call case 4: other requests
if (var_result === undefined) raiseUninitializedVariable("result");
var concat19 = request(var_result, "++(1)", [1], string20);
var_result = concat19;
if16 = GraceDone;
}
setLineNumber(308); // compilenode string
var string22 = new GraceString(" ");
// call case 4: other requests
// call case 4: other requests
var string25 = new GraceString(" ");
// call case 4: other requests
if (var_result === undefined) raiseUninitializedVariable("result");
var concat24 = request(var_result, "++(1)", [1], string25);
var concat23 = request(concat24, "++(1)", [1], var_connectingWord);
var concat21 = request(concat23, "++(1)", [1], string22);
var_result = concat21;
if14 = GraceDone;
} else {
var if26 = GraceDone;
setLineNumber(309); // compilenode num
// call case 4: other requests
if (var_count === undefined) raiseUninitializedVariable("count");
var term27 = request(var_count, ">(1)", [1], new GraceNum(1));
if (Grace_isTrue(term27)) {
setLineNumber(310); // compilenode string
var string29 = new GraceString(", ");
// call case 4: other requests
if (var_result === undefined) raiseUninitializedVariable("result");
var concat28 = request(var_result, "++(1)", [1], string29);
var_result = concat28;
if26 = GraceDone;
}
if14 = if26;
}
return if14;
};
let applyMeth10 = function apply_1 (argcv, ...args) {
if (this.guard.apply(this.receiver, args))
return this.real.apply(this.receiver, args);
badBlockArgs.apply(this, args);
};
applyMeth10.methodName = "apply(1)";
applyMeth10.paramCounts = [1];
applyMeth10.paramNames = ["v"];
applyMeth10.definitionLine = 303;
applyMeth10.definitionModule = "errormessages";
block10.methods["apply(1)"] = applyMeth10;
let matchesMeth10 = function matches_1 (argcv, ...args) {
return this.guard.apply(this.receiver, args) ? GraceTrue : GraceFalse;
};
matchesMeth10.methodName = "matches(1)";
matchesMeth10.paramCounts = [1];
matchesMeth10.paramNames = ["v"];
matchesMeth10.definitionLine = 303;
matchesMeth10.definitionModule = "errormessages";
block10.methods["matches(1)"] = matchesMeth10;
// call case 4: other requests
var call9 = request(var_xs, "do(1)", [1], block10);
if (var_result === undefined) raiseUninitializedVariable("result");
return var_result;
}; // end of method readableStringFrom(_)using(_)
setLineNumber(298); // compilenode member
var call30 = selfRequest(var_$dialect, "Collection", [0]);
var call31 = selfRequest(var_$dialect, "String", [0]);
func5.paramTypes = [call30, call31];
this.methods["readableStringFrom(1)using(1)"] = func5;
func5.methodName = "readableStringFrom(1)using(1)";
func5.paramCounts = [1, 1];
func5.paramNames = ["xs", "connectingWord"