Skip to content

Commit

Permalink
Hold AST child nodes in members (#690)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcauberer authored Dec 19, 2024
1 parent 2b4bf76 commit 3fc5c31
Show file tree
Hide file tree
Showing 46 changed files with 1,791 additions and 1,418 deletions.
3 changes: 2 additions & 1 deletion src/Spice.g4
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ enumItemLst: enumItem (COMMA enumItem)*;
enumItem: TYPE_IDENTIFIER (ASSIGN INT_LIT)?;
field: dataType IDENTIFIER (ASSIGN ternaryExpr)?;
signature: specifierLst? (F LESS dataType GREATER | P) IDENTIFIER (LESS typeLst GREATER)? LPAREN typeLst? RPAREN SEMICOLON;
stmt: (declStmt | assignExpr | returnStmt | breakStmt | continueStmt | fallthroughStmt) SEMICOLON;
stmt: (declStmt | exprStmt | returnStmt | breakStmt | continueStmt | fallthroughStmt) SEMICOLON;
declStmt: dataType IDENTIFIER (ASSIGN assignExpr)?;
exprStmt: assignExpr;
specifierLst: specifier+;
specifier: CONST | SIGNED | UNSIGNED | INLINE | PUBLIC | HEAP | COMPOSE;
modAttr: MOD_ATTR_PREAMBLE LBRACKET attrLst RBRACKET;
Expand Down
951 changes: 621 additions & 330 deletions src/ast/ASTBuilder.cpp

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/ast/ASTBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class ASTBuilder final : CompilerPass, public SpiceVisitor {
std::any visitSignature(SpiceParser::SignatureContext *ctx) override;
std::any visitStmt(SpiceParser::StmtContext *ctx) override;
std::any visitDeclStmt(SpiceParser::DeclStmtContext *ctx) override;
std::any visitExprStmt(SpiceParser::ExprStmtContext *ctx) override;
std::any visitSpecifierLst(SpiceParser::SpecifierLstContext *ctx) override;
std::any visitSpecifier(SpiceParser::SpecifierContext *ctx) override;
std::any visitTopLevelDefAttr(SpiceParser::TopLevelDefAttrContext *ctx) override;
Expand Down Expand Up @@ -131,6 +132,7 @@ class ASTBuilder final : CompilerPass, public SpiceVisitor {

// Private methods
template <typename T> T *createNode(const ParserRuleContext *ctx);
template <typename T> T *resumeForExpansion();
template <typename T> T *concludeNode(T *node);
ALWAYS_INLINE CodeLoc getCodeLoc(const ParserRuleContext *ctx) {
const size_t startIdx = ctx->start->getStartIndex();
Expand Down
199 changes: 92 additions & 107 deletions src/ast/ASTNodes.cpp

Large diffs are not rendered by default.

526 changes: 217 additions & 309 deletions src/ast/ASTNodes.h

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/ast/ASTVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ std::any ASTVisitor::visitSignature(SignatureNode *node) { return visitChildren(

std::any ASTVisitor::visitDeclStmt(DeclStmtNode *node) { return visitChildren(node); }

std::any ASTVisitor::visitExprStmt(ExprStmtNode *node) { return visitChildren(node); }

std::any ASTVisitor::visitSpecifierLst(SpecifierLstNode *node) { return visitChildren(node); }

std::any ASTVisitor::visitSpecifier(SpecifierNode *node) { return visitChildren(node); }
Expand All @@ -100,6 +102,8 @@ std::any ASTVisitor::visitFallthroughStmt(FallthroughStmtNode *node) { return vi

std::any ASTVisitor::visitAssertStmt(AssertStmtNode *node) { return visitChildren(node); }

std::any ASTVisitor::visitBuiltinCall(BuiltinCallNode *node) { return visitChildren(node); }

std::any ASTVisitor::visitPrintfCall(PrintfCallNode *node) { return visitChildren(node); }

std::any ASTVisitor::visitSizeofCall(SizeofCallNode *node) { return visitChildren(node); }
Expand Down
2 changes: 2 additions & 0 deletions src/ast/ASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class ASTVisitor : public AbstractASTVisitor {
std::any visitField(FieldNode *node) override;
std::any visitSignature(SignatureNode *node) override;
std::any visitDeclStmt(DeclStmtNode *node) override;
std::any visitExprStmt(ExprStmtNode *node) override;
std::any visitSpecifierLst(SpecifierLstNode *node) override;
std::any visitSpecifier(SpecifierNode *node) override;
std::any visitModAttr(ModAttrNode *node) override;
Expand All @@ -58,6 +59,7 @@ class ASTVisitor : public AbstractASTVisitor {
std::any visitContinueStmt(ContinueStmtNode *node) override;
std::any visitFallthroughStmt(FallthroughStmtNode *node) override;
std::any visitAssertStmt(AssertStmtNode *node) override;
std::any visitBuiltinCall(BuiltinCallNode *node) override;
std::any visitPrintfCall(PrintfCallNode *node) override;
std::any visitSizeofCall(SizeofCallNode *node) override;
std::any visitAlignofCall(AlignofCallNode *node) override;
Expand Down
4 changes: 4 additions & 0 deletions src/ast/AbstractASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class EnumItemNode;
class FieldNode;
class SignatureNode;
class DeclStmtNode;
class ExprStmtNode;
class SpecifierLstNode;
class SpecifierNode;
class ModAttrNode;
Expand All @@ -55,6 +56,7 @@ class BreakStmtNode;
class ContinueStmtNode;
class FallthroughStmtNode;
class AssertStmtNode;
class BuiltinCallNode;
class PrintfCallNode;
class SizeofCallNode;
class AlignofCallNode;
Expand Down Expand Up @@ -134,6 +136,7 @@ class AbstractASTVisitor {
virtual std::any visitField(FieldNode *node) = 0;
virtual std::any visitSignature(SignatureNode *node) = 0;
virtual std::any visitDeclStmt(DeclStmtNode *node) = 0;
virtual std::any visitExprStmt(ExprStmtNode *node) = 0;
virtual std::any visitSpecifierLst(SpecifierLstNode *node) = 0;
virtual std::any visitSpecifier(SpecifierNode *node) = 0;
virtual std::any visitModAttr(ModAttrNode *node) = 0;
Expand All @@ -147,6 +150,7 @@ class AbstractASTVisitor {
virtual std::any visitContinueStmt(ContinueStmtNode *node) = 0;
virtual std::any visitFallthroughStmt(FallthroughStmtNode *node) = 0;
virtual std::any visitAssertStmt(AssertStmtNode *node) = 0;
virtual std::any visitBuiltinCall(BuiltinCallNode *node) = 0;
virtual std::any visitPrintfCall(PrintfCallNode *node) = 0;
virtual std::any visitSizeofCall(SizeofCallNode *node) = 0;
virtual std::any visitAlignofCall(AlignofCallNode *node) = 0;
Expand Down
4 changes: 4 additions & 0 deletions src/ast/ParallelizableASTVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ std::any ParallelizableASTVisitor::visitSignature(const SignatureNode *node) { r

std::any ParallelizableASTVisitor::visitDeclStmt(const DeclStmtNode *node) { return visitChildren(node); }

std::any ParallelizableASTVisitor::visitExprStmt(const ExprStmtNode *node) { return visitChildren(node); }

std::any ParallelizableASTVisitor::visitSpecifierLst(const SpecifierLstNode *node) { return visitChildren(node); }

std::any ParallelizableASTVisitor::visitSpecifier(const SpecifierNode *node) { return visitChildren(node); }
Expand Down Expand Up @@ -111,6 +113,8 @@ std::any ParallelizableASTVisitor::visitFallthroughStmt(const FallthroughStmtNod

std::any ParallelizableASTVisitor::visitAssertStmt(const AssertStmtNode *node) { return visitChildren(node); }

std::any ParallelizableASTVisitor::visitBuiltinCall(const BuiltinCallNode *node) { return visitChildren(node); }

std::any ParallelizableASTVisitor::visitPrintfCall(const PrintfCallNode *node) { return visitChildren(node); }

std::any ParallelizableASTVisitor::visitSizeofCall(const SizeofCallNode *node) { return visitChildren(node); }
Expand Down
4 changes: 4 additions & 0 deletions src/ast/ParallelizableASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class EnumItemNode;
class FieldNode;
class SignatureNode;
class DeclStmtNode;
class ExprStmtNode;
class SpecifierLstNode;
class SpecifierNode;
class ModAttrNode;
Expand All @@ -55,6 +56,7 @@ class ReturnStmtNode;
class BreakStmtNode;
class ContinueStmtNode;
class FallthroughStmtNode;
class BuiltinCallNode;
class PrintfCallNode;
class SizeofCallNode;
class AlignofCallNode;
Expand Down Expand Up @@ -134,6 +136,7 @@ class ParallelizableASTVisitor {
virtual std::any visitField(const FieldNode *node);
virtual std::any visitSignature(const SignatureNode *node);
virtual std::any visitDeclStmt(const DeclStmtNode *node);
virtual std::any visitExprStmt(const ExprStmtNode *node);
virtual std::any visitSpecifierLst(const SpecifierLstNode *node);
virtual std::any visitSpecifier(const SpecifierNode *node);
virtual std::any visitModAttr(const ModAttrNode *node);
Expand All @@ -147,6 +150,7 @@ class ParallelizableASTVisitor {
virtual std::any visitContinueStmt(const ContinueStmtNode *node);
virtual std::any visitFallthroughStmt(const FallthroughStmtNode *node);
virtual std::any visitAssertStmt(const AssertStmtNode *node);
virtual std::any visitBuiltinCall(const BuiltinCallNode *node);
virtual std::any visitPrintfCall(const PrintfCallNode *node);
virtual std::any visitSizeofCall(const SizeofCallNode *node);
virtual std::any visitAlignofCall(const AlignofCallNode *node);
Expand Down
15 changes: 6 additions & 9 deletions src/importcollector/ImportCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ namespace spice::compiler {

std::any ImportCollector::visitEntry(EntryNode *node) {
// Visit all module attributes
for (ModAttrNode *attr : node->modAttrs())
for (ModAttrNode *attr : node->modAttrs)
visit(attr);

// Visit all import defs
for (ImportDefNode *importDef : node->importDefs())
for (ImportDefNode *importDef : node->importDefs)
visit(importDef);

return nullptr;
Expand Down Expand Up @@ -86,20 +86,17 @@ std::any ImportCollector::visitImportDef(ImportDefNode *node) {
}

std::any ImportCollector::visitModAttr(ModAttrNode *node) {
// Retrieve attributes
const AttrLstNode *attrs = node->attrLst();

// !!! Only bool attributes allowed here, due to missing attribute value checks being executed in a later stage !!!

// core.compiler.keep-on-name-collision
if (attrs->hasAttr(ATTR_CORE_COMPILER_KEEP_ON_NAME_COLLISION)) {
const bool keepOnCollision = attrs->getAttrValueByName(ATTR_CORE_COMPILER_KEEP_ON_NAME_COLLISION)->boolValue;
if (node->attrLst->hasAttr(ATTR_CORE_COMPILER_KEEP_ON_NAME_COLLISION)) {
const bool keepOnCollision = node->attrLst->getAttrValueByName(ATTR_CORE_COMPILER_KEEP_ON_NAME_COLLISION)->boolValue;
sourceFile->alwaysKeepSymbolsOnNameCollision = keepOnCollision;
}

// core.compiler.warnings.ignore
if (attrs->hasAttr(ATTR_CORE_COMPILER_WARNINGS_IGNORE)) {
const bool ignoreWarnings = attrs->getAttrValueByName(ATTR_CORE_COMPILER_WARNINGS_IGNORE)->boolValue;
if (node->attrLst->hasAttr(ATTR_CORE_COMPILER_WARNINGS_IGNORE)) {
const bool ignoreWarnings = node->attrLst->getAttrValueByName(ATTR_CORE_COMPILER_WARNINGS_IGNORE)->boolValue;
sourceFile->ignoreWarnings = ignoreWarnings;
}

Expand Down
36 changes: 26 additions & 10 deletions src/irgenerator/GenBuiltinFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,23 @@

namespace spice::compiler {

std::any IRGenerator::visitBuiltinCall(const BuiltinCallNode *node) {
if (node->printfCall)
return visit(node->printfCall);
if (node->sizeofCall)
return visit(node->sizeofCall);
if (node->alignofCall)
return visit(node->alignofCall);
if (node->lenCall)
return visit(node->lenCall);
if (node->panicCall)
return visit(node->panicCall);
if (node->sysCall)
return visit(node->sysCall);
assert_fail("Unknown builtin call");
return nullptr;
}

std::any IRGenerator::visitPrintfCall(const PrintfCallNode *node) {
// Retrieve printf function
llvm::Function *printfFct = stdFunctionManager.getPrintfFct();
Expand All @@ -19,7 +36,7 @@ std::any IRGenerator::visitPrintfCall(const PrintfCallNode *node) {
printfArgs.push_back(templateString);

// Collect replacement arguments
for (const AssignExprNode *arg : node->args()) {
for (const AssignExprNode *arg : node->args) {
// Retrieve type of argument
const QualType argSymbolType = arg->getEvaluatedSymbolType(manIdx);

Expand Down Expand Up @@ -58,9 +75,9 @@ std::any IRGenerator::visitPrintfCall(const PrintfCallNode *node) {
std::any IRGenerator::visitSizeofCall(const SizeofCallNode *node) {
llvm::Type *type;
if (node->isType) { // Size of type
type = any_cast<llvm::Type *>(visit(node->dataType()));
type = any_cast<llvm::Type *>(visit(node->dataType));
} else { // Size of value
type = node->assignExpr()->getEvaluatedSymbolType(manIdx).toLLVMType(sourceFile);
type = node->assignExpr->getEvaluatedSymbolType(manIdx).toLLVMType(sourceFile);
}
// Calculate size at compile-time
const llvm::TypeSize sizeInBits = module->getDataLayout().getTypeSizeInBits(type);
Expand All @@ -73,9 +90,9 @@ std::any IRGenerator::visitSizeofCall(const SizeofCallNode *node) {
std::any IRGenerator::visitAlignofCall(const AlignofCallNode *node) {
llvm::Type *type;
if (node->isType) { // Align of type
type = any_cast<llvm::Type *>(visit(node->dataType()));
type = any_cast<llvm::Type *>(visit(node->dataType));
} else { // Align of value
type = node->assignExpr()->getEvaluatedSymbolType(manIdx).toLLVMType(sourceFile);
type = node->assignExpr->getEvaluatedSymbolType(manIdx).toLLVMType(sourceFile);
}
// Calculate size at compile-time
const llvm::Align align = module->getDataLayout().getABITypeAlign(type);
Expand All @@ -87,13 +104,13 @@ std::any IRGenerator::visitAlignofCall(const AlignofCallNode *node) {

std::any IRGenerator::visitLenCall(const LenCallNode *node) {
// Check if the length is fixed and known via the symbol type
QualType symbolType = node->assignExpr()->getEvaluatedSymbolType(manIdx);
QualType symbolType = node->assignExpr->getEvaluatedSymbolType(manIdx);
symbolType = symbolType.removeReferenceWrapper();

llvm::Value *lengthValue;
if (symbolType.is(TY_STRING)) {
llvm::Function *getRawLengthFct = stdFunctionManager.getStringGetRawLengthStringFct();
lengthValue = builder.CreateCall(getRawLengthFct, resolveValue(node->assignExpr()));
lengthValue = builder.CreateCall(getRawLengthFct, resolveValue(node->assignExpr));
} else {
assert(symbolType.isArray() && symbolType.getArraySize() != ARRAY_SIZE_UNKNOWN);
// Return length value
Expand Down Expand Up @@ -134,11 +151,10 @@ std::any IRGenerator::visitSysCall(const SysCallNode *node) {
llvm::InlineAsm *inlineAsm = llvm::InlineAsm::get(fctType, asmString, constraints, true);

// Fill arguments array (first argument is syscall number)
const std::vector<AssignExprNode *> assignExprs = node->assignExprs();
llvm::Value *argValues[NUM_REGS];
for (unsigned short i = 0; i < NUM_REGS; i++) {
if (i < assignExprs.size()) {
const AssignExprNode *argNode = assignExprs.at(i);
if (i < node->args.size()) {
const AssignExprNode *argNode = node->args.at(i);
const QualType &argType = argNode->getEvaluatedSymbolType(manIdx);
assert(argType.isOneOf({TY_INT, TY_LONG, TY_SHORT, TY_BOOL, TY_BYTE, TY_PTR, TY_STRING}));
if (argType.isOneOf({TY_PTR, TY_STRING}))
Expand Down
Loading

0 comments on commit 3fc5c31

Please sign in to comment.