Minor refactoring of components and names

This commit is contained in:
Mattia Giambirtone 2023-10-11 15:51:43 +02:00
parent 4c8cf89c8e
commit f2a23b8b77
Signed by: nocturn9x
GPG Key ID: 8270F9F467971E59
6 changed files with 210 additions and 568 deletions

View File

@ -1,2 +1,2 @@
--hints:off
--hints:off --deepCopy:on
path="src"

View File

@ -17,8 +17,9 @@ import std/os
# These variables can be tweaked to debug and test various components of the toolchain
var debugLexer* = false # Print the tokenizer's output
var debugParser* = false # Print the AST generated by the parser
var debugLexer* = false # Print the tokenizer's output (main module only)
var debugParser* = false # Print the AST generated by the parser (main module only)
var debugTypeChecker* = false # Debug the typechecker's output (main module only)
var debugCompiler* = false # Disassemble and/or print the code generated by the compiler
const debugVM* {.booldefine.} = false # Enable the runtime debugger in the bytecode VM
const debugGC* {.booldefine.} = false # Debug the Garbage Collector (extremely verbose)
@ -58,16 +59,10 @@ Options
-h, --help Show this help text and exit
-v, --version Print the current peon version and exit
-s, --string Execute the passed string as if it was a file
-m, --mode Set the compilation mode. Acceptable values are 'debug' and
'release'. Defaults to 'debug'
-c, --compile Compile the code, but do not execute it. Useful along with -d
-w, --warnings Turn warnings on or off (default: on). Acceptable values are
yes/on and no/off
--noWarn Disable a specific warning (for example, --noWarn:unusedVariable)
--noWarn Disable a specific warning (for example, --noWarn:UserWarning)
--showMismatches Show all mismatches when function dispatching fails (output is really verbose)
--target Select the compilation target (valid values are: 'c' and 'bytecode'). Defaults to
'bytecode'
-o, --output Rename the output file to this value
--debug-lexer Show the lexer's output
--debug-parser Show the parser's output
--debug-tc Show the typechecker's output

File diff suppressed because it is too large Load Diff

View File

@ -252,8 +252,8 @@ type
VarDecl* = ref object of Declaration
name*: IdentExpr
isConst*: bool
isLet*: bool
constant*: bool
mutable*: bool
valueType*: Expression
value*: Expression
@ -626,16 +626,16 @@ proc newIfStmt*(condition: Expression, thenBranch, elseBranch: Statement,
proc newVarDecl*(name: IdentExpr, valueType, value: Expression, token: Token,
isConst: bool = false, isPrivate: bool = true, isLet: bool = false,
constant: bool = false, isPrivate: bool = true, mutable: bool = false,
pragmas: seq[Pragma] = @[]): VarDecl =
result = VarDecl(kind: varDecl)
result.name = name
result.valueType = valueType
result.value = value
result.isConst = isConst
result.constant = constant
result.isPrivate = isPrivate
result.token = token
result.isLet = isLet
result.mutable = mutable
result.pragmas = pragmas
@ -714,7 +714,11 @@ proc `$`*(self: ASTNode): string =
var self = ExprStmt(self)
result &= &"ExpressionStatement({self.expression})"
of breakStmt:
result = "Break()"
var self = BreakStmt(self)
if self.label.isNil:
result = "Break()"
else:
result = &"Break({self.label})"
of importStmt:
var self = ImportStmt(self)
result &= &"Import({self.moduleName})"
@ -759,7 +763,7 @@ proc `$`*(self: ASTNode): string =
result &= &"AwaitStmt({self.expression})"
of varDecl:
var self = VarDecl(self)
result &= &"Var(name={self.name}, type={self.valueType}, value={self.value}, let={self.isLet}, const={self.isConst}, private={self.isPrivate}, pragmas={self.pragmas})"
result &= &"Var(name={self.name}, type={self.valueType}, value={self.value}, mutable={self.mutable}, constant={self.constant}, private={self.isPrivate}, pragmas={self.pragmas})"
of funDecl:
var self = FunDecl(self)
result &= &"""FunDecl(name={self.name}, body={self.body}, type={self.returnType}, arguments=[{self.arguments.join(", ")}], defaults=[{self.defaults.join(", ")}], generics=[{self.generics.join(", ")}], async={self.isAsync}, generator={self.isGenerator}, private={self.isPrivate}, pragmas={self.pragmas})"""
@ -822,7 +826,7 @@ proc getRelativeBoundaries*(self: ASTNode): tuple[start, stop: int] =
of binaryExpr:
var self = BinaryExpr(self)
result = (getRelativeBoundaries(self.a).start, getRelativeBoundaries(self.b).stop)
of intExpr, binExpr, hexExpr, octExpr, strExpr, floatExpr:
of intExpr, binExpr, hexExpr, octExpr, strExpr, floatExpr, trueExpr, falseExpr:
var self = LiteralExpr(self)
result = self.literal.relPos
of identExpr:

View File

@ -302,7 +302,7 @@ proc expect[T: TokenType or string](self: Parser, kind: openarray[T], message: s
proc expression(self: Parser): Expression
proc expressionStatement(self: Parser): Statement
proc statement(self: Parser): Statement
proc varDecl(self: Parser, isLet: bool = false, isConst: bool = false): Declaration
proc varDecl(self: Parser): Declaration
proc parseFunExpr(self: Parser): LambdaExpr
proc funDecl(self: Parser, isAsync: bool = false, isGenerator: bool = false, isLambda: bool = false, isOperator: bool = false): Declaration
proc declaration(self: Parser): Declaration
@ -904,8 +904,7 @@ proc parsePragmas(self: Parser): seq[Pragma] =
continue
proc varDecl(self: Parser, isLet: bool = false,
isConst: bool = false): Declaration =
proc varDecl(self: Parser): Declaration =
## Parses variable declarations
var tok = self.peek(-1)
self.expect(Identifier, &"expecting identifier after '{tok.lexeme}'")
@ -920,8 +919,6 @@ proc varDecl(self: Parser, isLet: bool = false,
valueType = self.parseOr()
if self.match("="):
value = self.expression()
if isConst and not value.isConst():
self.error("constant initializer is not a constant")
if value.isNil() and tok.kind == TokenType.Let:
self.error("let declaration requires an initializer")
self.expect(Semicolon, &"expecting semicolon after '{tok.lexeme}' declaration")
@ -930,11 +927,13 @@ proc varDecl(self: Parser, isLet: bool = false,
pragmas.add(pragma)
case tok.kind:
of TokenType.Var:
result = newVarDecl(name, valueType=valueType, value=value, isPrivate=isPrivate, token=tok, pragmas=pragmas)
result = newVarDecl(name, valueType=valueType, value=value, isPrivate=isPrivate, token=tok, pragmas=pragmas, mutable=true)
of TokenType.Const:
result = newVarDecl(name, valueType=valueType, value=value, isPrivate=isPrivate, token=tok, isConst=true, pragmas=pragmas)
if not value.isConst():
self.error("constant initializer is not a constant")
result = newVarDecl(name, valueType=valueType, value=value, isPrivate=isPrivate, token=tok, constant=true, pragmas=pragmas)
of TokenType.Let:
result = newVarDecl(name, valueType=valueType, value=value, isPrivate=isPrivate, token=tok, isLet=isLet, pragmas=pragmas)
result = newVarDecl(name, valueType=valueType, value=value, isPrivate=isPrivate, token=tok, pragmas=pragmas)
else:
discard # Unreachable
result.file = self.file
@ -1320,9 +1319,8 @@ proc declaration(self: Parser): Declaration =
## Parses declarations
case self.peek().kind:
of TokenType.Var, TokenType.Const, Let:
let keyword = self.step()
result = self.varDecl(isLet = keyword.kind == Let,
isConst = keyword.kind == TokenType.Const)
discard self.step()
result = self.varDecl()
of Function:
discard self.step()
result = self.funDecl()

View File

@ -89,7 +89,7 @@ proc test(warnings: seq[WarningKind] = @[], mismatches: bool = false) =
if tokens.len() == 0:
continue
if debugLexer:
styledEcho fgCyan, "Tokenization step:"
styledEcho fgCyan, "Tokenizer output:"
for i, token in tokens:
if i == tokens.high():
# Who cares about EOF?
@ -100,15 +100,15 @@ proc test(warnings: seq[WarningKind] = @[], mismatches: bool = false) =
if tree.len() == 0:
continue
if debugParser:
styledEcho fgCyan, "Parsing step:"
styledEcho fgCyan, "Parser output:"
for node in tree:
styledEcho fgGreen, "\t", $node
echo ""
if debugCompiler:
styledEcho fgCyan, "Compilation step:"
if debugTypeChecker:
styledEcho fgCyan, "Typechecker output:"
for typedNode in typeChecker.validate(parser.parse(lexer.lex(input, "<stdin>"), lexer.getFile(), lexer.getLines(), lexer.getSource()),
lexer.getFile(), lexer.getSource(), showMismatches=mismatches, disabledWarnings=warnings):
if debugCompiler:
if debugTypeChecker:
styledEcho fgGreen, &"\t{typedNode.node} -> {typeChecker.stringify(typedNode)}\n"
echo ""
except LexingError:
@ -207,19 +207,13 @@ when isMainModule:
mismatches = true
of "noWarn":
case value:
of "unusedVariable":
warnings.add(WarningKind.UnusedName)
of "unreachableCode":
warnings.add(WarningKind.UnreachableCode)
of "shadowOuterScope":
warnings.add(WarningKind.ShadowOuterScope)
of "mutateOuterScope":
warnings.add(WarningKind.MutateOuterScope)
of "UserWarning":
warnings.add(UserWarning)
else:
stderr.styledWriteLine(fgRed, styleBright, "Error: ", fgDefault, "invalid warning name for option 'noWarn'")
quit()
of "debug-tc":
debugCompiler = true
debugTypeChecker = true
of "compile":
run = false
of "output":