Skip to content

Commit

Permalink
add files
Browse files Browse the repository at this point in the history
  • Loading branch information
StunxFS committed Dec 25, 2023
1 parent 53b0992 commit 05d48ae
Show file tree
Hide file tree
Showing 4 changed files with 229 additions and 0 deletions.
36 changes: 36 additions & 0 deletions lib/rivet/src/ast/ImportedSymbol.ri
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this
// source code is governed by an MIT license that can be found in the LICENSE
// file.

import ../token;

#[boxed]
pub struct ImportedSymbol {
pub name: string;
pub sym: Sym;
pub pos: token.Pos;
pub mut is_used: bool;
}

pub struct ImportedSymbols {
pub mut syms: []ImportedSymbol;

#[inline]
pub func add(mut self, name: string, sym: Sym, pos: token.Pos, is_used: bool := false) {
self.syms.push(ImportedSymbol(name, sym, pos, is_used));
}

pub func find(&self, name: string) -> ?ImportedSymbol {
for imported_sym in self.syms {
if name == imported_sym.name {
return imported_sym;
}
}
return none;
}

#[inline]
pub func exists(&self, name: string) -> bool {
return self.find(name) != none;
}
}
61 changes: 61 additions & 0 deletions lib/rivet/src/ast/Node.ri
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this
// source code is governed by an MIT license that can be found in the LICENSE
// file.

import std/traits.Stringable;

import ../token;

#[boxed]
pub enum Node < Stringable {
Decl(Decl),
Stmt(Stmt),
Expr(Expr);

pub func position(self) -> token.Pos {
return match self {
.Decl(decl) -> decl.position(),
.Stmt(stmt) -> stmt.position(),
.Expr(expr) -> expr.position()
};
}

pub func to_string(self) -> string {
return match self {
/*.Decl(decl) -> decl.to_string(),
.Stmt(stmt) -> stmt.to_string(),*/
.Expr(expr) -> expr.to_string(),
else -> "<not-implemented>"
};
}
}
pub func nodes_to_decls(nodes: []mut Node) -> []mut Decl {
mut decls := []mut Decl();
for node in nodes {
if node is .Decl(decl) {
decls.push(decl);
}
}
return decls;
}
pub func nodes_to_stmts(nodes: []mut Node) -> []mut Stmt {
mut stmts := []mut Stmt();
for node in nodes {
if node is .Stmt(stmt) {
stmts.push(stmt);
}
}
return stmts;
}
pub func nodes_to_exprs(nodes: []mut Node) -> []mut Expr {
mut exprs := []mut Expr();
for node in nodes {
if node is .Expr(expr) {
exprs.push(expr);
}
}
return exprs;
}
55 changes: 55 additions & 0 deletions lib/rivet/src/ast/comptime.ri
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this
// source code is governed by an MIT license that can be found in the LICENSE
// file.

import ../token;
import ../report;

pub struct ComptimeIf {
mut branches: []mut ComptimeIfBranch;
mut branch_idx: ?uint;
has_else: bool;
pos: token.Pos;
mut type: Type;

pub func nodes(self) -> ?[]Node {
if branch_idx := self.branch_idx {
return self.branches[branch_idx].nodes;
}
return none;
}
}

pub struct ComptimeIfBranch {
pub mut cond: Expr;
pub is_else: bool;
pub is_else_if: bool;
pub mut nodes: []mut Node;
pub pos: token.Pos;
pub mut type: Type;
}

extend Env {
pub func evalue_comptime_if(self, mut comptime_if: ComptimeIf) -> []mut Node {
for i, branch in comptime_if.branches {
if branch.is_else && comptime_if.branch_idx == none {
comptime_if.branch_idx = i;
} else if cond := self.evalue_comptime_condition(branch.cond); cond {
comptime_if.branch_idx = i;
}
if branch_idx := comptime_if.branch_idx {
return comptime_if.branches[branch_idx].nodes;
}
}
return +[];
}

func evalue_comptime_condition(self, cond: Expr) -> ?bool {
return match cond {
else -> {
report.error("invalid comptime condition", cond.position());
none
}
};
}
}
77 changes: 77 additions & 0 deletions lib/rivet/src/parser/comptime.ri
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright (C) 2023-present Jose Mendoza - All rights reserved. Use of this
// source code is governed by an MIT license that can be found in the LICENSE
// file.

import ../ast;
import ../report;

extend Parser {
enum ComptimeLevel as uint8 {
Decl,
Stmt,
Expr
}

func parse_nodes(mut self, level: ComptimeLevel) -> []mut ast.Node {
return match level {
.Decl -> {
mut decls := []mut ast.Node();
if self.accept(.Lbrace) {
while self.tok.kind != .Rbrace {
decls.push(.Decl(self.parse_decl()))
}
self.expect(.Rbrace);
} else {
decls.push(.Decl(self.parse_decl()))
}
decls
},
.Stmt -> {
mut stmts := []mut ast.Node();
if self.accept(.Lbrace) {
while self.tok.kind != .Rbrace {
stmts.push(.Stmt(self.parse_stmt()));
}
self.expect(.Rbrace);
} else {
stmts.push(.Stmt(self.parse_stmt()));
}
stmts
},
.Expr -> +[.Expr(self.parse_expr())]
};
}

func parse_comptime_if(mut self, level: ComptimeLevel) -> ast.ComptimeIf {
mut branches := []mut ast.ComptimeIfBranch();
mut has_else := false;
mut pos := self.tok.pos;
while self.tok.kind in [.KwIf, .KwElse] {
branch_pos := self.tok.pos;
if self.accept(.KwElse) && self.tok.kind != .KwIf {
branches.push(
ast.ComptimeIfBranch(
.Empty(self.tok.pos), nodes: self.parse_nodes(level),
is_else: true, pos: branch_pos + self.prev_tok.pos
)
);
has_else = true;
break;
}
is_else_if := self.prev_tok.kind == .KwElse;
self.expect(.KwIf);
cond := self.parse_expr();
branches.push(
ast.ComptimeIfBranch(
cond, nodes: self.parse_nodes(level), is_else_if: is_else_if,
pos: branch_pos + self.prev_tok.pos
)
);
if self.tok.kind != .KwElse {
break;
}
}
pos += self.prev_tok.pos;
return ast.ComptimeIf(branches, has_else: has_else, pos: pos);
}
}

0 comments on commit 05d48ae

Please sign in to comment.