Skip to content

Commit

Permalink
Extend parser bootstrap (#463)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcauberer committed Feb 12, 2024
1 parent 8fe6612 commit 7fa3ca9
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 13 deletions.
4 changes: 2 additions & 2 deletions src-bootstrap/ast/ast-nodes.spice
Expand Up @@ -370,9 +370,9 @@ public type ASTAttrNode struct /*: IVisitable*/ {

}

// ========================================================= ConstantLstNode =====================================================
// ========================================================= CaseConstantNode ====================================================

public type ASTConstantLstNode struct /*: IVisitable*/ {
public type ASTCaseConstantNode struct /*: IVisitable*/ {
compose public ASTNode node

}
Expand Down
27 changes: 20 additions & 7 deletions src-bootstrap/parser/parser.spice
Expand Up @@ -553,7 +553,11 @@ f<ASTCaseBranchNode*> Parser.parseCaseBranch() {
dyn caseBranchNode = this.createNode<ASTCaseBranchNode>();

this.lexer.expect(TokenType::CASE);
this.parseConstantLst();
this.parseCaseConstant();
while this.currentTokenIs(TokenType::COMMA) {
this.lexer.expect(TokenType::COMMA);
this.parseCaseConstant();
}
this.lexer.expect(TokenType::COLON);
this.parseStmtLst();

Expand Down Expand Up @@ -873,16 +877,25 @@ f<ASTAttrNode*> Parser.parseAttr() {
return this.concludeNode(attrNode);
}

f<ASTConstantLstNode*> Parser.parseConstantLst() {
dyn constantLstNode = this.createNode<ASTConstantLstNode>();
f<ASTCaseConstantNode*> Parser.parseCaseConstant() {
dyn caseConstantNode = this.createNode<ASTCaseConstantNode>();

this.parseConstant();
while this.currentTokenIs(TokenType::COMMA) {
this.lexer.expect(TokenType::COMMA);
const dyn optionsVarExpr = [TokenType::IDENTIFIER, TokenType::TYPE_IDENTIFIER];
if this.currentTokenIsOneOf(optionsVarExpr, sizeof(optionsVarExpr)) {
if this.currentTokenIs(TokenType::TYPE_IDENTIFIER) {
this.lexer.advance();
this.lexer.expect(TokenType::SCOPE_ACCESS);
}
this.lexer.expect(TokenType::TYPE_IDENTIFIER);
while this.currentTokenIs(TokenType::SCOPE_ACCESS) {
this.lexer.expect(TokenType::SCOPE_ACCESS);
this.lexer.expect(TokenType::TYPE_IDENTIFIER);
}
} else {
this.parseConstant();
}

return this.concludeNode(constantLstNode);
return this.concludeNode(caseConstantNode);
}

f<ASTReturnStmtNode*> Parser.parseReturnStmt() {
Expand Down
36 changes: 35 additions & 1 deletion src-bootstrap/util/block-allocator.spice
@@ -1,17 +1,51 @@
// Std imports
import "std/data/vector";
import "std/type/error";
import "std/os/system";

// Own imports
import "../util/memory";

type Base dyn;

public type BlockAllocator<Base> struct {
const MemoryManager& memoryManager
IMemoryManager* memoryManager
Vector<byte*> memoryBlocks
Vector<Base*> allocatedObjects
unsigned int blockSize
unsigned int offsetInBlock = 0
}

public p BlockAllocator.ctor(IMemoryManager* memoryManager, unsigned int blockSize = 0) {
this.memoryManager = memoryManager;
this.blockSize = blockSize == 0 ? getPageSize() : blockSize;
// Allocate the first block
this.allocateNewBlock();
}

public p BlockAllocator.dtor() {
// Destruct all objects
foreach Base* ptr : this.allocatedObjects {
sDelete(ptr);
}
this.allocatedObjects.clear();

// Free all memory blocks
foreach byte* block : this.memoryBlocks {
this.memoryManager.deallocate(block);
}
this.memoryBlocks.clear();
}

public p BlockAllocator.allocateNewBlock() {
// Allocate new block
byte* ptr = this.memoryManager.allocate(this.blockSize);
if ptr != nil<byte*> {
String msg = "Could not allocate memory block for BlockAllocator. Already allocated " + this.memoryBlocks.size() + " blocks.";
panic(Error(msg));
}

// Store pointer and reset offset
this.memoryBlocks.push(ptr);
this.offsetInBlock = 0;
}
7 changes: 4 additions & 3 deletions src-bootstrap/util/memory.spice
@@ -1,12 +1,13 @@
public type IMemoryManager interface {
f<heap byte*> allocate(unsigned long);
p deallocate(heap byte*&);
public f<heap byte*> allocate(unsigned long);
public p deallocate(heap byte*&);
}

public type DefaultMemoryManager struct : IMemoryManager {}

public f<heap byte*> DefaultMemoryManager.allocate(unsigned long size) {
return sAlloc(size);
Result<heap byte*> allocation = sAlloc(size);
return allocation.unwrap();
}

public p DefaultMemoryManager.deallocate(heap byte*& ptr) {
Expand Down

0 comments on commit 7fa3ca9

Please sign in to comment.