Skip to content

Commit

Permalink
feat: macros
Browse files Browse the repository at this point in the history
It's only possible to use them but not declare yet
  • Loading branch information
MilkeeyCat committed Oct 17, 2024
1 parent 2c989ad commit 6a079b1
Show file tree
Hide file tree
Showing 4 changed files with 418 additions and 43 deletions.
246 changes: 236 additions & 10 deletions src/macros/macros.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,75 @@
use std::ffi::{c_char, CStr};

use crate::lexer;
use libloading::Symbol;
use std::ffi::{c_char, CStr, CString};

#[repr(C)]
pub enum Literal {
String(*const i8),
Int(i64),
UInt(u64),
}

#[repr(C)]
#[derive(Debug)]
pub enum Token {
Literal(Literal),
Ident(*mut c_char),
Integer(*mut c_char),
String(*mut c_char),

Assign,
Plus,
Minus,
Bang,
Asterisk,
Slash,
Arrow,
Period,
Tilde,
Ampersand,
Bar,
Equal,
NotEqual,
LessThan,
GreaterThan,
LessEqual,
GreaterEqual,
And,
Or,
Shl,
Shr,
Comma,
Semicolon,
Colon,
LParen,
RParen,
LBrace,
RBrace,
LBracket,
RBracket,

Const,
True,
False,
Let,
Fn,
Enum,
Struct,
If,
While,
For,
Else,
Return,
As,
Continue,
Break,

U8,
U16,
U32,
U64,
I8,
I16,
I32,
I64,
Usize,
Isize,
Bool,
Void,

Null,
}

#[repr(C)]
Expand Down Expand Up @@ -50,3 +108,171 @@ pub fn symbol_to_macros<'lib>(symbol: Symbol<'lib, *const Slice<Macro>>) -> &'li
std::slice::from_raw_parts(slice.ptr, slice.len)
}
}

impl Into<Token> for lexer::Token {
fn into(self) -> Token {
match self {
Self::Ident(ident) => {
let ident = Box::leak(Box::new(CString::new(ident).unwrap()));

Token::Ident(ident.as_ptr() as *mut c_char)
}
Self::String(string) => {
let string = Box::leak(Box::new(CString::new(string).unwrap()));

Token::String(string.as_ptr() as *mut c_char)
}
Self::Integer(integer) => {
let integer = Box::leak(Box::new(CString::new(integer).unwrap()));

Token::Integer(integer.as_ptr() as *mut c_char)
}

Self::Assign => Token::Assign,
Self::Plus => Token::Plus,
Self::Minus => Token::Minus,
Self::Bang => Token::Bang,
Self::Asterisk => Token::Asterisk,
Self::Slash => Token::Slash,
Self::Arrow => Token::Arrow,
Self::Period => Token::Period,
Self::Tilde => Token::Tilde,
Self::Ampersand => Token::Ampersand,
Self::Bar => Token::Bar,
Self::Equal => Token::Equal,
Self::NotEqual => Token::NotEqual,
Self::LessThan => Token::LessThan,
Self::GreaterThan => Token::GreaterThan,
Self::LessEqual => Token::LessEqual,
Self::GreaterEqual => Token::GreaterEqual,
Self::And => Token::And,
Self::Or => Token::Or,
Self::Shl => Token::Shl,
Self::Shr => Token::Shr,
Self::Comma => Token::Comma,
Self::Semicolon => Token::Semicolon,
Self::Colon => Token::Colon,
Self::LParen => Token::LParen,
Self::RParen => Token::RParen,
Self::LBrace => Token::LBrace,
Self::RBrace => Token::RBrace,
Self::LBracket => Token::LBracket,
Self::RBracket => Token::RBracket,

Self::Const => Token::Const,
Self::True => Token::True,
Self::False => Token::False,
Self::Let => Token::Let,
Self::Fn => Token::Fn,
Self::Enum => Token::Enum,
Self::Struct => Token::Struct,
Self::If => Token::If,
Self::While => Token::While,
Self::For => Token::For,
Self::Else => Token::Else,
Self::Return => Token::Return,
Self::As => Token::As,
Self::Continue => Token::Continue,
Self::Break => Token::Break,

Self::U8 => Token::U8,
Self::U16 => Token::U16,
Self::U32 => Token::U32,
Self::U64 => Token::U64,
Self::I8 => Token::I8,
Self::I16 => Token::I16,
Self::I32 => Token::I32,
Self::I64 => Token::I64,
Self::Usize => Token::Usize,
Self::Isize => Token::Isize,
Self::Bool => Token::Bool,
Self::Void => Token::Void,

Self::Null => Token::Null,
}
}
}

impl Into<lexer::Token> for Token {
fn into(self) -> lexer::Token {
match self {
Self::Ident(ptr) => {
let ident = unsafe { CString::from_raw(ptr) }.into_string().unwrap();

lexer::Token::Ident(ident)
}
Self::String(ptr) => {
let string = unsafe { CString::from_raw(ptr) }.into_string().unwrap();

lexer::Token::String(string)
}
Self::Integer(ptr) => {
let integer = unsafe { CString::from_raw(ptr) }.into_string().unwrap();

lexer::Token::Integer(integer)
}

Self::Assign => lexer::Token::Assign,
Self::Plus => lexer::Token::Plus,
Self::Minus => lexer::Token::Minus,
Self::Bang => lexer::Token::Bang,
Self::Asterisk => lexer::Token::Asterisk,
Self::Slash => lexer::Token::Slash,
Self::Arrow => lexer::Token::Arrow,
Self::Period => lexer::Token::Period,
Self::Tilde => lexer::Token::Tilde,
Self::Ampersand => lexer::Token::Ampersand,
Self::Bar => lexer::Token::Bar,
Self::Equal => lexer::Token::Equal,
Self::NotEqual => lexer::Token::NotEqual,
Self::LessThan => lexer::Token::LessThan,
Self::GreaterThan => lexer::Token::GreaterThan,
Self::LessEqual => lexer::Token::LessEqual,
Self::GreaterEqual => lexer::Token::GreaterEqual,
Self::And => lexer::Token::And,
Self::Or => lexer::Token::Or,
Self::Shl => lexer::Token::Shl,
Self::Shr => lexer::Token::Shr,
Self::Comma => lexer::Token::Comma,
Self::Semicolon => lexer::Token::Semicolon,
Self::Colon => lexer::Token::Colon,
Self::LParen => lexer::Token::LParen,
Self::RParen => lexer::Token::RParen,
Self::LBrace => lexer::Token::LBrace,
Self::RBrace => lexer::Token::RBrace,
Self::LBracket => lexer::Token::LBracket,
Self::RBracket => lexer::Token::RBracket,

Self::Const => lexer::Token::Const,
Self::True => lexer::Token::True,
Self::False => lexer::Token::False,
Self::Let => lexer::Token::Let,
Self::Fn => lexer::Token::Fn,
Self::Enum => lexer::Token::Enum,
Self::Struct => lexer::Token::Struct,
Self::If => lexer::Token::If,
Self::While => lexer::Token::While,
Self::For => lexer::Token::For,
Self::Else => lexer::Token::Else,
Self::Return => lexer::Token::Return,
Self::As => lexer::Token::As,
Self::Continue => lexer::Token::Continue,
Self::Break => lexer::Token::Break,

Self::U8 => lexer::Token::U8,
Self::U16 => lexer::Token::U16,
Self::U32 => lexer::Token::U32,
Self::U64 => lexer::Token::U64,
Self::I8 => lexer::Token::I8,
Self::I16 => lexer::Token::I16,
Self::I32 => lexer::Token::I32,
Self::I64 => lexer::Token::I64,
Self::Usize => lexer::Token::Usize,
Self::Isize => lexer::Token::Isize,
Self::Bool => lexer::Token::Bool,
Self::Void => lexer::Token::Void,

Self::Null => lexer::Token::Null,
}
}
}
1 change: 1 addition & 0 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ pub use error::ParserError;
pub use expr::*;
pub use op::{BinOp, BitwiseOp, CmpOp, OpParseError, UnOp};
pub use parser::Parser;
pub use precedence::Precedence;
pub use stmt::{Block, Stmt, StmtFor, StmtFunction, StmtIf, StmtReturn, StmtVarDecl, StmtWhile};
76 changes: 47 additions & 29 deletions src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ impl<T: Iterator<Item = Result<Token, LexerError>>> Parser<T> {
Ok(stmts)
}

fn expr(&mut self, precedence: Precedence) -> Result<Expr, ParserError> {
pub fn expr(&mut self, precedence: Precedence) -> Result<Expr, ParserError> {
let token = match self.cur_token.as_ref().unwrap() {
Token::Ident(_) => Token::Ident(Default::default()),
Token::Integer(_) => Token::Integer(Default::default()),
Expand All @@ -149,6 +149,7 @@ impl<T: Iterator<Item = Result<Token, LexerError>>> Parser<T> {
};

while !self.cur_token_is(&Token::Semicolon)
&& self.cur_token.is_some()
&& precedence < Precedence::from(self.cur_token.as_ref().unwrap())
{
left = match self.infix_fns.get(self.cur_token.as_ref().unwrap()) {
Expand Down Expand Up @@ -247,41 +248,45 @@ impl<T: Iterator<Item = Result<Token, LexerError>>> Parser<T> {
Ok(())
}

fn stmt(&mut self) -> Result<Option<Stmt>, ParserError> {
match self.cur_token.as_ref().unwrap() {
Token::Return => Ok(Some(self.parse_return()?)),
Token::If => Ok(Some(self.if_stmt()?)),
Token::While => Ok(Some(self.while_stmt()?)),
Token::For => Ok(Some(self.for_stmt()?)),
Token::Let => Ok(Some(self.var_decl()?)),
Token::Continue => {
self.expect(&Token::Continue)?;
self.expect(&Token::Semicolon)?;

Ok(Some(Stmt::Continue))
}
Token::Break => {
self.expect(&Token::Break)?;
self.expect(&Token::Semicolon)?;

Ok(Some(Stmt::Break))
}
Token::Fn => self.function(true),
_ => {
let expr = Stmt::Expr(self.expr(Precedence::default())?);

self.expect(&Token::Semicolon)?;

Ok(Some(expr))
}
}
}

fn compound_statement(&mut self, scope_kind: ScopeKind) -> Result<Block, ParserError> {
let mut stmts = Vec::new();

self.scope.enter_new(scope_kind);
self.expect(&Token::LBrace)?;

while !self.cur_token_is(&Token::RBrace) {
match self.cur_token.as_ref().unwrap() {
Token::Return => stmts.push(self.parse_return()?),
Token::If => stmts.push(self.if_stmt()?),
Token::While => stmts.push(self.while_stmt()?),
Token::For => stmts.push(self.for_stmt()?),
Token::Let => stmts.push(self.var_decl()?),
Token::Continue => {
self.expect(&Token::Continue)?;
self.expect(&Token::Semicolon)?;
stmts.push(Stmt::Continue);
}
Token::Break => {
self.expect(&Token::Break)?;
self.expect(&Token::Semicolon)?;
stmts.push(Stmt::Break);
}
Token::Fn => {
if let Some(stmt) = self.function(true)? {
stmts.push(stmt)
}
}
_ => {
let expr = Stmt::Expr(self.expr(Precedence::default())?);

self.expect(&Token::Semicolon)?;

stmts.push(expr);
}
if let Some(stmt) = self.stmt()? {
stmts.push(stmt);
}
}

Expand All @@ -293,6 +298,19 @@ impl<T: Iterator<Item = Result<Token, LexerError>>> Parser<T> {
})
}

// This function is used only by macro expansion
pub fn parse_stmts(&mut self) -> Result<Vec<Stmt>, ParserError> {
let mut stmts = Vec::new();

while self.cur_token.is_some() {
if let Some(stmt) = self.stmt()? {
stmts.push(stmt);
}
}

Ok(stmts)
}

fn parse_type(&mut self) -> Result<Type, ParserError> {
let mut n = 0;
while self.cur_token_is(&Token::Asterisk) {
Expand Down
Loading

0 comments on commit 6a079b1

Please sign in to comment.