Skip to content

Commit

Permalink
rename: selene (merge #5)
Browse files Browse the repository at this point in the history
  • Loading branch information
SrGaabriel authored Sep 5, 2024
1 parent 173a3d3 commit 20fd4b3
Show file tree
Hide file tree
Showing 86 changed files with 660 additions and 664 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Gwydion CI/CD
name: Selene CI/CD

on:
push:
Expand Down Expand Up @@ -48,9 +48,9 @@ jobs:
- name: Rename and upload compiler artifacts
run: |
mkdir -p artifacts
cp compiler/build/libs/gwydion.jar artifacts/gwydion-compiler-jvm.jar
cp compiler/build/bin/linuxX64/releaseExecutable/compiler.kexe artifacts/gwydion-compiler-linuxX64
cp compiler/build/bin/windowsX64/releaseExecutable/compiler.exe artifacts/gwydion-compiler-windowsX64.exe
cp compiler/build/libs/selene.jar artifacts/selene-compiler-jvm.jar
cp compiler/build/bin/linuxX64/releaseExecutable/compiler.kexe artifacts/selene-compiler-linuxX64
cp compiler/build/bin/windowsX64/releaseExecutable/compiler.exe artifacts/selene-compiler-windowsX64.exe
- uses: actions/upload-artifact@v3
with:
name: compiler-artifacts
Expand Down Expand Up @@ -80,9 +80,9 @@ jobs:
uses: softprops/action-gh-release@v1
with:
files: |
compiler-artifacts/gwydion-compiler-jvm.jar
compiler-artifacts/gwydion-compiler-linuxX64
compiler-artifacts/gwydion-compiler-windowsX64.exe
compiler-artifacts/selene-compiler-jvm.jar
compiler-artifacts/selene-compiler-linuxX64
compiler-artifacts/selene-compiler-windowsX64.exe
jester/jester
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# 🐉 gwydion
# 🍂 selene

---

This is a project I created to learn more about low-level programming and delve into the world of compilers. The goal is to create a simple programming language that compiles to LLVM IR.
Selene is a statically-typed, imperative and procedural programming language compiled to LLVM IR.

You may look at the code and think the means to my desired end are incorrect and/or inefficient. That's not a bug, but a feature, as they say in San Francisco. I'm doing this to learn and mess around, so I won't hesitate to break stuff if it means I'll learn something new.
The language is designed to be as easy to grasp as possible, while still providing a powerful set of features. It aims to combine the best of all worlds, providing a simple and easy-to-understand syntax, while still being powerful enough to be used in real-world applications.

---

# Example
# Examples

Basic input/output:
```go
Expand Down
40 changes: 20 additions & 20 deletions analysis/src/commonMain/kotlin/Errors.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package me.gabriel.gwydion.analysis
package me.gabriel.selene.analysis

import me.gabriel.gwydion.frontend.GwydionType
import me.gabriel.gwydion.frontend.lexing.TokenKind
import me.gabriel.gwydion.frontend.parsing.CallNode
import me.gabriel.gwydion.frontend.parsing.SyntaxTreeNode
import me.gabriel.selene.frontend.SeleneType
import me.gabriel.selene.frontend.lexing.TokenKind
import me.gabriel.selene.frontend.parsing.CallNode
import me.gabriel.selene.frontend.parsing.SyntaxTreeNode

data class AnalysisResult(
val errors: MutableList<AnalysisError> = mutableListOf(),
val warnings: MutableList<AnalysisWarning> = mutableListOf()
)

sealed class AnalysisError(val message: String, val node: SyntaxTreeNode) {
class InvalidOperation(node: SyntaxTreeNode, leftType: GwydionType, operator: TokenKind, rightType: GwydionType) : AnalysisError(
class InvalidOperation(node: SyntaxTreeNode, leftType: SeleneType, operator: TokenKind, rightType: SeleneType) : AnalysisError(
"invalid operation: cannot run $operator.sig on ${leftType.signature} and ${rightType.signature}",
node
)
Expand All @@ -24,7 +24,7 @@ sealed class AnalysisError(val message: String, val node: SyntaxTreeNode) {
node
)

class ReturnTypeMismatch(node: SyntaxTreeNode, expected: GwydionType, actual: GwydionType) : AnalysisError(
class ReturnTypeMismatch(node: SyntaxTreeNode, expected: SeleneType, actual: SeleneType) : AnalysisError(
"return type mismatch: expected ${expected.signature}, got ${actual.signature}",
node
)
Expand All @@ -44,12 +44,12 @@ sealed class AnalysisError(val message: String, val node: SyntaxTreeNode) {
node
)

class UnknownType(node: SyntaxTreeNode, type: GwydionType) : AnalysisError(
class UnknownType(node: SyntaxTreeNode, type: SeleneType) : AnalysisError(
"unknown type: ${type.signature}",
node
)

class InvalidCondition(node: SyntaxTreeNode, type: GwydionType) : AnalysisError(
class InvalidCondition(node: SyntaxTreeNode, type: SeleneType) : AnalysisError(
"invalid condition: condition must be a boolean expression, got ${type.signature}",
node
)
Expand All @@ -58,7 +58,7 @@ sealed class AnalysisError(val message: String, val node: SyntaxTreeNode) {
"undefined array: $name",
node
)
class NotAnArray(node: SyntaxTreeNode, type: GwydionType) : AnalysisError(
class NotAnArray(node: SyntaxTreeNode, type: SeleneType) : AnalysisError(
"not an array: ${type.signature}",
node
)
Expand All @@ -71,7 +71,7 @@ sealed class AnalysisError(val message: String, val node: SyntaxTreeNode) {
class MissingArgumentsForInstantiation(
node: SyntaxTreeNode,
name: String,
arguments: Map<String, GwydionType>
arguments: Map<String, SeleneType>
) : AnalysisError(
"missing arguments for instantiation of $name: ${arguments.keys.joinToString(", ") {
"$it (${arguments[it]!!.signature})"
Expand Down Expand Up @@ -122,7 +122,7 @@ sealed class AnalysisError(val message: String, val node: SyntaxTreeNode) {
function: String,
trait: String,
struct: String,
correct: List<GwydionType>,
correct: List<SeleneType>,
) : AnalysisError(
"wrong function signature `$function` in trait impl $trait for $struct, expected${
if (correct.isEmpty()) " no parameters"
Expand All @@ -131,7 +131,7 @@ sealed class AnalysisError(val message: String, val node: SyntaxTreeNode) {
node
)

class BinaryOpTypeMismatch(node: SyntaxTreeNode, left: GwydionType, right: GwydionType) : AnalysisError(
class BinaryOpTypeMismatch(node: SyntaxTreeNode, left: SeleneType, right: SeleneType) : AnalysisError(
"binary operation type mismatch: ${left.signature} and ${right.signature}",
node
)
Expand All @@ -141,7 +141,7 @@ sealed class AnalysisError(val message: String, val node: SyntaxTreeNode) {
node
)

class WrongArgumentTypeForInstantiation(node: SyntaxTreeNode, expected: GwydionType, provided: GwydionType) : AnalysisError(
class WrongArgumentTypeForInstantiation(node: SyntaxTreeNode, expected: SeleneType, provided: SeleneType) : AnalysisError(
"wrong argument type for instantiation: expected ${expected.signature}, got ${provided.signature}",
node
)
Expand All @@ -162,19 +162,19 @@ sealed class AnalysisError(val message: String, val node: SyntaxTreeNode) {
class ArrayElementTypeMismatch(
node: SyntaxTreeNode,
index: Int,
provided: GwydionType,
expected: GwydionType
provided: SeleneType,
expected: SeleneType
): AnalysisError(
"array element type mismatch: expected ${expected.signature}, got ${provided.signature} at index $index",
node
)

class NotADataStructure(node: SyntaxTreeNode, type: GwydionType) : AnalysisError(
class NotADataStructure(node: SyntaxTreeNode, type: SeleneType) : AnalysisError(
"not a data structure: ${type.signature}",
node
)

class InvalidStructAccess(node: SyntaxTreeNode, struct: GwydionType) : AnalysisError(
class InvalidStructAccess(node: SyntaxTreeNode, struct: SeleneType) : AnalysisError(
"invalid struct access: ${struct.signature}",
node
)
Expand All @@ -184,12 +184,12 @@ sealed class AnalysisError(val message: String, val node: SyntaxTreeNode) {
node
)

class WrongArgumentTypeForFunctionCall(node: SyntaxTreeNode, expected: GwydionType, actual: GwydionType) : AnalysisError(
class WrongArgumentTypeForFunctionCall(node: SyntaxTreeNode, expected: SeleneType, actual: SeleneType) : AnalysisError(
"wrong argument type for function call: expected ${expected.signature}, got ${actual.signature}",
node
)

class TypeCannotBeMutable(node: SyntaxTreeNode, type: GwydionType) : AnalysisError(
class TypeCannotBeMutable(node: SyntaxTreeNode, type: SeleneType) : AnalysisError(
"type cannot be mutable: ${type.signature}",
node
)
Expand Down
20 changes: 10 additions & 10 deletions analysis/src/commonMain/kotlin/SemanticAnalysisManager.kt
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package me.gabriel.gwydion.analysis
package me.gabriel.selene.analysis

import me.gabriel.gwydion.analysis.analyzers.ISemanticAnalyzer
import me.gabriel.gwydion.analysis.analyzers.TypeInferenceVisitor
import me.gabriel.gwydion.analysis.analyzers.impl.*
import me.gabriel.gwydion.analysis.signature.Signatures
import me.gabriel.gwydion.frontend.parsing.*
import me.gabriel.gwydion.tools.GwydionLogger
import me.gabriel.gwydion.tools.LogLevel
import me.gabriel.selene.analysis.analyzers.ISemanticAnalyzer
import me.gabriel.selene.analysis.analyzers.TypeInferenceVisitor
import me.gabriel.selene.analysis.analyzers.impl.*
import me.gabriel.selene.analysis.signature.Signatures
import me.gabriel.selene.frontend.parsing.*
import me.gabriel.selene.tools.SeleneLogger
import me.gabriel.selene.tools.LogLevel

class SemanticAnalysisManager(
private val logger: GwydionLogger,
private val logger: SeleneLogger,
private val symbols: SymbolRepository,
private val signatures: Signatures,
) {
Expand Down Expand Up @@ -65,7 +65,7 @@ class SemanticAnalysisManager(
}

val newBlock = analyzers.map { analyzer ->
val visitor = TypeInferenceVisitor(node)
val visitor = TypeInferenceVisitor()

val switchBlock = @Suppress("UNCHECKED_CAST")
(analyzer as ISemanticAnalyzer<SyntaxTreeNode>).register(block, node, signatures, visitor)
Expand Down
24 changes: 12 additions & 12 deletions analysis/src/commonMain/kotlin/SymbolBlock.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package me.gabriel.gwydion.analysis
package me.gabriel.selene.analysis

import me.gabriel.gwydion.frontend.GwydionType
import me.gabriel.gwydion.frontend.parsing.*
import me.gabriel.selene.frontend.SeleneType
import me.gabriel.selene.frontend.parsing.*

class SymbolRepository(val module: String) {
val root = SymbolBlock(
Expand All @@ -14,7 +14,7 @@ class SymbolRepository(val module: String) {
fun createBlock(
id: SyntaxTreeNode,
parent: SymbolBlock,
self: GwydionType? = parent.self
self: SeleneType? = parent.self
): SymbolBlock {
val block = SymbolBlock(module, id, parent, mutableListOf(), self)
parent.children.add(block)
Expand All @@ -27,10 +27,10 @@ class SymbolBlock(
val id: SyntaxTreeNode?,
val parent: SymbolBlock?,
val children: MutableList<SymbolBlock> = mutableListOf(),
var self: GwydionType? = parent?.self
var self: SeleneType? = parent?.self
) {
private val symbols = mutableMapOf<String, GwydionType>()
private val definitions = mutableMapOf<SyntaxTreeNode, GwydionType>()
private val symbols = mutableMapOf<String, SeleneType>()
private val definitions = mutableMapOf<SyntaxTreeNode, SeleneType>()

val name get() = when (id) {
is FunctionNode -> id.name
Expand All @@ -40,7 +40,7 @@ class SymbolBlock(

fun createChild(
id: SyntaxTreeNode,
self: GwydionType? = this.self
self: SeleneType? = this.self
): SymbolBlock {
val block = SymbolBlock(module, id, this, mutableListOf(), self)
children.add(block)
Expand All @@ -51,19 +51,19 @@ class SymbolBlock(
return children.find { it.id == id }
}

fun declareSymbol(name: String, type: GwydionType) {
fun declareSymbol(name: String, type: SeleneType) {
symbols[name] = type
}

fun defineSymbol(node: SyntaxTreeNode, type: GwydionType) {
fun defineSymbol(node: SyntaxTreeNode, type: SeleneType) {
definitions[node] = type
}

fun resolveSymbol(name: String): GwydionType? {
fun resolveSymbol(name: String): SeleneType? {
return symbols[name] ?: parent?.resolveSymbol(name)
}

fun resolveExpression(node: SyntaxTreeNode): GwydionType? {
fun resolveExpression(node: SyntaxTreeNode): SeleneType? {
return when (node) {
is TypedSyntaxTreeNode -> node.type
is VariableReferenceNode -> resolveSymbol(node.name)
Expand Down
10 changes: 5 additions & 5 deletions analysis/src/commonMain/kotlin/analyzers/ISemanticAnalyzer.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package me.gabriel.gwydion.analysis.analyzers
package me.gabriel.selene.analysis.analyzers

import me.gabriel.gwydion.analysis.AnalysisResult
import me.gabriel.gwydion.analysis.SymbolBlock
import me.gabriel.gwydion.analysis.signature.Signatures
import me.gabriel.gwydion.frontend.parsing.SyntaxTreeNode
import me.gabriel.selene.analysis.AnalysisResult
import me.gabriel.selene.analysis.SymbolBlock
import me.gabriel.selene.analysis.signature.Signatures
import me.gabriel.selene.frontend.parsing.SyntaxTreeNode

interface ISemanticAnalyzer<T : SyntaxTreeNode> {
fun handles(node: SyntaxTreeNode): Boolean
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package me.gabriel.gwydion.analysis.analyzers
package me.gabriel.selene.analysis.analyzers

import me.gabriel.gwydion.frontend.parsing.SyntaxTreeNode
import me.gabriel.selene.frontend.parsing.SyntaxTreeNode
import kotlin.reflect.KClass

abstract class SingleNodeAnalyzer<T : SyntaxTreeNode>(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package me.gabriel.gwydion.analysis.analyzers
package me.gabriel.selene.analysis.analyzers

import me.gabriel.gwydion.frontend.parsing.SyntaxTreeNode
import me.gabriel.selene.frontend.parsing.SyntaxTreeNode

class TypeInferenceVisitor(private val node: SyntaxTreeNode) {
class TypeInferenceVisitor {
val queuedVisits = mutableListOf<Pair<SyntaxTreeNode, () -> Any>>()

fun <T : Any> visit(node: SyntaxTreeNode, block: () -> T) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package me.gabriel.gwydion.analysis.analyzers.impl
package me.gabriel.selene.analysis.analyzers.impl

import me.gabriel.gwydion.analysis.AnalysisResult
import me.gabriel.gwydion.analysis.SymbolBlock
import me.gabriel.gwydion.analysis.analyzers.SingleNodeAnalyzer
import me.gabriel.gwydion.analysis.analyzers.TypeInferenceVisitor
import me.gabriel.gwydion.analysis.signature.Signatures
import me.gabriel.gwydion.frontend.GwydionType
import me.gabriel.gwydion.frontend.parsing.ArrayAccessNode
import me.gabriel.gwydion.frontend.workingBase
import me.gabriel.selene.analysis.AnalysisResult
import me.gabriel.selene.analysis.SymbolBlock
import me.gabriel.selene.analysis.analyzers.SingleNodeAnalyzer
import me.gabriel.selene.analysis.analyzers.TypeInferenceVisitor
import me.gabriel.selene.analysis.signature.Signatures
import me.gabriel.selene.frontend.SeleneType
import me.gabriel.selene.frontend.parsing.ArrayAccessNode
import me.gabriel.selene.frontend.workingBase

class ArrayAccessAnalyzer: SingleNodeAnalyzer<ArrayAccessNode>(ArrayAccessNode::class) {
override fun register(
Expand All @@ -18,8 +18,8 @@ class ArrayAccessAnalyzer: SingleNodeAnalyzer<ArrayAccessNode>(ArrayAccessNode::
): SymbolBlock {
val resolved = block.resolveExpression(node.array) ?: return block
val type = when (val base = resolved.workingBase()) {
is GwydionType.FixedArray -> base.baseType
is GwydionType.DynamicArray -> base.baseType
is SeleneType.FixedArray -> base.baseType
is SeleneType.DynamicArray -> base.baseType
else -> return block
}

Expand Down
Loading

0 comments on commit 20fd4b3

Please sign in to comment.