Initial ground work on the C backend

This commit is contained in:
Mattia Giambirtone 2022-12-15 16:49:27 +01:00
parent cc5622605d
commit db021cb821
4 changed files with 103 additions and 11 deletions

View File

@ -50,6 +50,10 @@ export ast, token, symbols, config, errors
type
PragmaKind* = enum
## An enumeration of pragma types
Immediate,
Delayed
TypeKind* = enum
## An enumeration of compile-time
## types
@ -144,6 +148,7 @@ type
# Is this name a builtin?
isBuiltin*: bool
WarningKind* {.pure.} = enum
## A warning enumeration type
UnreachableCode, UnusedName, ShadowOuterScope,
@ -200,13 +205,15 @@ type
currentModule*: Name
# The module importing us, if any
parentModule*: Name
# Currently imported modules
modules*: HashSet[Name]
## Public getters for nicer error formatting
proc getCurrentNode*(self: Compiler): ASTNode = (if self.current >= self.ast.len(): self.ast[^1] else: self.ast[self.current - 1])
proc getCurrentFunction*(self: Compiler): Declaration {.inline.} = (if self.currentFunction.isNil(): nil else: self.currentFunction.valueType.fun)
## Some "forward declarations" here (they're actually stubs because nim forces forward declarations to be
## Some forward declarations (some of them arere actually stubs because nim forces forward declarations to be
## implemented in the same module). They are methods because we need to dispatch to their actual specific
## implementations inside each target module, so we need the runtime type of the compiler object to be
## taken into account
@ -313,8 +320,8 @@ proc step*(self: Compiler): ASTNode {.inline.} =
self.current += 1
# Peon's type inference system is very flexible and can be
# reused across multiple compilation backends
# Peon's type inference and name resolution system is very flexible
# and can be reused across multiple compilation backends
proc resolve*(self: Compiler, name: string): Name =
## Traverses all existing namespaces and returns

View File

@ -11,6 +11,8 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
## The code generator for Peon bytecode
import std/tables
import std/strformat
import std/algorithm
@ -19,8 +21,6 @@ import std/strutils
import std/sequtils
import std/sets
import std/os
import std/terminal
import std/hashes
import opcodes
@ -35,10 +35,6 @@ export opcodes
type
PragmaKind* = enum
## An enumeration of pragma types
Immediate,
Delayed
CompilerFunc = object
## An internal compiler function called
@ -96,8 +92,6 @@ type
namedBlocks: seq[NamedBlock]
# Compiler procedures called by pragmas
compilerProcs: TableRef[string, CompilerFunc]
# Currently imported modules
modules: HashSet[Name]
# Stores the position of all jumps
jumps: seq[tuple[patched: bool, offset: int]]
# Metadata about function locations

View File

@ -0,0 +1,70 @@
# Copyright 2022 Mattia Giambirtone & All Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
## The code generator for translating peon to C code
import std/tables
import std/strformat
import std/algorithm
import std/parseutils
import std/strutils
import std/sequtils
import std/sets
import std/os
import frontend/compiler/compiler
import frontend/parsing/lexer
import frontend/parsing/parser
import frontend/parsing/ast
type
CompilerFunc = object
## An internal compiler function called
## by pragmas
kind: PragmaKind
handler: proc (self: NativeCCompiler, pragma: Pragma, name: Name)
NativeCCompiler* = ref object of Compiler
## The peon to C compiler
# Compiler procedures called by pragmas
compilerProcs: TableRef[string, CompilerFunc]
proc newNativeCCompiler*(replMode: bool = false): NativeCCompiler =
## Initializes a new, blank, NativeCCompiler
## object
new(result)
result.ast = @[]
result.current = 0
result.file = ""
result.names = @[]
result.depth = 0
result.lines = @[]
result.currentFunction = nil
result.replMode = replMode
result.currentModule = nil
result.compilerProcs = newTable[string, CompilerFunc]()
result.source = ""
result.lexer = newLexer()
result.lexer.fillSymbolTable()
result.parser = newParser()
result.isMainModule = false
result.disabledWarnings = @[]
method literal*(self: Compiler, node: ASTNode, compile: bool = true): Type {.discardable.} =
## Compiles literal expressions

View File

@ -0,0 +1,21 @@
# Copyright 2022 Mattia Giambirtone & All Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
## Reusable objects to simplify code generation using templates
type
CodeGenerator* = ref object of RootObj
## A generic code generator
code: string
vars: seq[tuple[name, value: string]]