Minor fixes and changes, renamed nodump option to noDump, added missing support for mode flag. Minor additions and style fixes to parser and compiler
This commit is contained in:
parent
8b0d6b7ebe
commit
2187aa19d8
|
@ -56,7 +56,7 @@ Options
|
|||
-h, --help Show this help text and exits
|
||||
-v, --version Print the current peon version and exits
|
||||
-s, --string Execute the passed string as if it was a file
|
||||
-n, --nodump Don't dump the result of compilation to a *.pbc file
|
||||
-n, --noDump Don't dump the result of compilation to a *.pbc file
|
||||
-b, --breakpoints Run the debugger at specific bytecode offsets (comma-separated).
|
||||
Only available when compiled with VM debugging on
|
||||
-d, --disassemble Disassemble the given bytecode file instead of executing it
|
||||
|
@ -65,5 +65,5 @@ Options
|
|||
--warnings Turn warnings on/off (default: on). Acceptable values are
|
||||
yes/on and no/off
|
||||
--noWarn Disable a specific warning (for example, --noWarn unusedVariable)
|
||||
--showMismatches Show all mismatches when dispatching function calls (quite verbose!)
|
||||
--showMismatches Show all mismatches when dispatching function calls fails (quite verbose!)
|
||||
"""
|
||||
|
|
|
@ -277,7 +277,6 @@ proc handleErrorPragma(self: Compiler, pragma: Pragma, name: Name)
|
|||
proc dispatchPragmas(self: Compiler, name: Name)
|
||||
proc dispatchDelayedPragmas(self: Compiler, name: Name)
|
||||
proc funDecl(self: Compiler, node: FunDecl, name: Name)
|
||||
proc typeDecl(self: Compiler, node: TypeDecl, name: Name)
|
||||
proc compileModule(self: Compiler, module: Name)
|
||||
proc generateCall(self: Compiler, fn: Name, args: seq[Expression], line: int)
|
||||
proc prepareFunction(self: Compiler, fn: Name)
|
||||
|
@ -351,7 +350,9 @@ proc error(self: Compiler, message: string, node: ASTNode = nil) {.raises: [Comp
|
|||
|
||||
|
||||
proc warning(self: Compiler, kind: WarningKind, message: string, name: Name = nil, node: ASTNode = nil) =
|
||||
## Raises a warning
|
||||
## Raises a warning. Note that warnings are always disabled in REPL mode
|
||||
if self.replMode or kind in self.disabledWarnings:
|
||||
return
|
||||
var node: ASTNode = node
|
||||
var fn: Declaration
|
||||
if name.isNil():
|
||||
|
@ -370,19 +371,28 @@ proc warning(self: Compiler, kind: WarningKind, message: string, name: Name = ni
|
|||
if not name.isNil():
|
||||
file = name.owner.file
|
||||
var pos = node.getRelativeBoundaries()
|
||||
#let line = self.source.splitLines()[node.token.line - 1].strip(chars={'\n'})
|
||||
if file notin ["<string>", ""]:
|
||||
file = relativePath(file, getCurrentDir())
|
||||
if kind notin self.disabledWarnings:
|
||||
stderr.styledWrite(fgYellow, styleBright, "Warning in ", fgRed, &"{file}:{node.token.line}:{pos.start}")
|
||||
if not fn.isNil() and fn.kind == funDecl:
|
||||
stderr.styledWrite(fgYellow, styleBright, " in function ", fgRed, FunDecl(fn).name.token.lexeme)
|
||||
stderr.styledWriteLine(styleBright, fgDefault, ": ", message)
|
||||
#[
|
||||
stderr.styledWrite(fgYellow, styleBright, "Source line: ", resetStyle, fgDefault, line[0..<pos.start])
|
||||
stderr.styledWrite(fgYellow, styleUnderscore, line[pos.start..pos.stop])
|
||||
stderr.styledWriteLine(fgDefault, line[pos.stop + 1..^1])
|
||||
]#
|
||||
stderr.styledWrite(fgYellow, styleBright, "Warning in ", fgRed, &"{file}:{node.token.line}:{pos.start}")
|
||||
if not fn.isNil() and fn.kind == funDecl:
|
||||
stderr.styledWrite(fgYellow, styleBright, " in function ", fgRed, FunDecl(fn).name.token.lexeme)
|
||||
stderr.styledWriteLine(styleBright, fgDefault, ": ", message)
|
||||
try:
|
||||
# We try to be as specific as possible with the warning message, pointing to the
|
||||
# line it belongs to, but since warnings are almost never raised from the source
|
||||
# file they're generated in, we take into account the fact that retrieving the
|
||||
# exact warning location may fail and bail out silently if it does
|
||||
let line = readFile(file).splitLines()[node.token.line - 1].strip(chars={'\n'})
|
||||
stderr.styledWrite(fgYellow, styleBright, "Source line: ", resetStyle, fgDefault, line[0..<pos.start])
|
||||
stderr.styledWrite(fgYellow, styleUnderscore, line[pos.start..pos.stop])
|
||||
stderr.styledWriteLine(fgDefault, line[pos.stop + 1..^1])
|
||||
except IOError:
|
||||
discard
|
||||
except OSError:
|
||||
discard
|
||||
except IndexDefect:
|
||||
# Something probably went wrong (wrong line metadata): bad idea to crash!
|
||||
discard
|
||||
|
||||
|
||||
proc step(self: Compiler): ASTNode {.inline.} =
|
||||
|
@ -629,8 +639,6 @@ proc compileDecl(self: Compiler, name: Name) =
|
|||
# Now we just dispatch to one of our functions to
|
||||
# compile the declaration
|
||||
case name.kind:
|
||||
of NameKind.CustomType:
|
||||
self.typeDecl(TypeDecl(name.node), name)
|
||||
of NameKind.Function:
|
||||
# Generic functions need to be compiled at
|
||||
# the call site because we need to know the
|
||||
|
@ -1175,14 +1183,14 @@ proc matchImpl(self: Compiler, name: string, kind: Type, node: ASTNode = nil, al
|
|||
if name.valueType.kind != Function:
|
||||
msg &= ": not a callable"
|
||||
elif kind.args.len() != name.valueType.args.len():
|
||||
msg &= &": wrong number of arguments ({name.valueType.args.len()} expected, got {kind.args.len()})"
|
||||
msg &= &": wrong number of arguments (expected {name.valueType.args.len()}, got {kind.args.len()})"
|
||||
else:
|
||||
for i, arg in kind.args:
|
||||
if name.valueType.args[i].kind.mutable and not arg.kind.mutable:
|
||||
msg &= &": first mismatch at position {i + 1}: {name.valueType.args[i].name} is immutable, not 'var'"
|
||||
break
|
||||
elif not self.compare(arg.kind, name.valueType.args[i].kind):
|
||||
msg &= &": first mismatch at position {i + 1}: ({self.typeToStr(name.valueType.args[i].kind)} expected, got {self.typeToStr(arg.kind)})"
|
||||
msg &= &": first mismatch at position {i + 1}: (expected {self.typeToStr(name.valueType.args[i].kind)}, got {self.typeToStr(arg.kind)})"
|
||||
break
|
||||
else:
|
||||
msg &= " (compile with --showMismatches for more details)"
|
||||
|
@ -1380,10 +1388,7 @@ proc endScope(self: Compiler) =
|
|||
# (it may need them later)
|
||||
names.delete(names.high())
|
||||
continue
|
||||
if not name.resolved and not self.replMode:
|
||||
# We don't emit this warning in replMode because
|
||||
# a variable might be declared on one line and then
|
||||
# used on the next
|
||||
if not name.resolved:
|
||||
case name.kind:
|
||||
of NameKind.Var:
|
||||
if not name.ident.token.lexeme.startsWith("_") and name.isPrivate:
|
||||
|
@ -1452,13 +1457,13 @@ proc declareName(self: Compiler, node: ASTNode, mutable: bool = false) =
|
|||
## on the stack
|
||||
var declaredName: string = ""
|
||||
var n: Name
|
||||
if self.names.high() > 16777215:
|
||||
# If someone ever hits this limit in real-world scenarios, I swear I'll
|
||||
# slap myself 100 times with a sign saying "I'm dumb". Mark my words
|
||||
self.error("cannot declare more than 16777215 names at a time")
|
||||
case node.kind:
|
||||
of NodeKind.varDecl:
|
||||
var node = VarDecl(node)
|
||||
if self.names.high() > 16777215:
|
||||
# If someone ever hits this limit in real-world scenarios, I swear I'll
|
||||
# slap myself 100 times with a sign saying "I'm dumb". Mark my words
|
||||
self.error("cannot declare more than 16777215 variables at a time")
|
||||
declaredName = node.name.token.lexeme
|
||||
# Creates a new Name entry so that self.identifier emits the proper stack offset
|
||||
self.names.add(Name(depth: self.depth,
|
||||
|
@ -2500,11 +2505,7 @@ proc varDecl(self: Compiler, node: VarDecl) =
|
|||
self.declareName(node)
|
||||
var name = self.names[^1]
|
||||
name.valueType = typ
|
||||
|
||||
|
||||
proc typeDecl(self: Compiler, node: TypeDecl, name: Name) =
|
||||
## Compiles type declarations
|
||||
# TODO
|
||||
|
||||
|
||||
|
||||
proc funDecl(self: Compiler, node: FunDecl, name: Name) =
|
||||
|
|
|
@ -139,7 +139,11 @@ proc newOperatorTable: OperatorTable =
|
|||
result.tokens = @[]
|
||||
for prec in Precedence:
|
||||
result.precedence[prec] = @[]
|
||||
result.addOperator("=") # Assignment is the only builtin
|
||||
# Assignment and attribute accessing are (currently)
|
||||
# the only builtins that cannot be easily implemented
|
||||
# from within peon itself
|
||||
result.addOperator("=")
|
||||
result.addOperator(".")
|
||||
|
||||
|
||||
proc getPrecedence(self: OperatorTable, lexeme: string): Precedence =
|
||||
|
@ -1293,7 +1297,6 @@ proc parse*(self: Parser, tokens: seq[Token], file: string, lines: seq[tuple[sta
|
|||
self.tree = @[]
|
||||
if not persist:
|
||||
self.operators = newOperatorTable()
|
||||
self.operators.addOperator("=")
|
||||
self.findOperators(tokens)
|
||||
while not self.done():
|
||||
self.tree.add(self.declaration())
|
||||
|
|
13
src/main.nim
13
src/main.nim
|
@ -261,12 +261,21 @@ when isMainModule:
|
|||
var breaks: seq[uint64] = @[]
|
||||
var dis: bool = false
|
||||
var mismatches: bool = false
|
||||
var mode: CompileMode = CompileMode.Debug
|
||||
for kind, key, value in optParser.getopt():
|
||||
case kind:
|
||||
of cmdArgument:
|
||||
file = key
|
||||
of cmdLongOption:
|
||||
case key:
|
||||
of "mode":
|
||||
if value.toLowerAscii() == "release":
|
||||
mode = CompileMode.Release
|
||||
elif value.toLowerAscii() == "debug":
|
||||
discard
|
||||
else:
|
||||
stderr.styledWriteLine(fgRed, styleBright, "Error: ", fgDefault, "invalid value for option 'mode' (valid options are: debug, release)")
|
||||
quit()
|
||||
of "help":
|
||||
echo HELP_MESSAGE
|
||||
quit()
|
||||
|
@ -276,7 +285,7 @@ when isMainModule:
|
|||
of "string":
|
||||
file = key
|
||||
fromString = true
|
||||
of "no-dump":
|
||||
of "noDump":
|
||||
dump = false
|
||||
of "warnings":
|
||||
if value.toLowerAscii() in ["yes", "on"]:
|
||||
|
@ -349,7 +358,7 @@ when isMainModule:
|
|||
if file == "":
|
||||
repl()
|
||||
else:
|
||||
runFile(file, fromString, dump, breaks, dis, warnings, mismatches)
|
||||
runFile(file, fromString, dump, breaks, dis, warnings, mismatches, mode)
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue