Skip to content

Commit

Permalink
huge refactor in parser and working on cast_as expression
Browse files Browse the repository at this point in the history
  • Loading branch information
tahadostifam committed Feb 10, 2025
1 parent 7d6a143 commit a8a285f
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 59 deletions.
10 changes: 10 additions & 0 deletions ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,18 @@ pub enum Expression {
Dereference(Box<Expression>),
StructInit(StructInit),
StructFieldAccess(Box<StructFieldAccess>),
CastAs(CastAs)
}

#[derive(Debug, Clone)]
pub struct CastAs {
pub expr: Box<Expression>,
pub cast_as: TokenKind,
pub span: Span,
pub loc: Location
}


#[derive(Debug, Clone)]
pub enum UnaryOperatorType {
PreIncrement,
Expand Down
9 changes: 9 additions & 0 deletions ast/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ impl fmt::Display for UnaryOperatorType {
}
}

impl fmt::Display for CastAs {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} as {}", self.expr, self.cast_as)
}
}

impl fmt::Display for Expression {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Expand Down Expand Up @@ -165,6 +171,9 @@ impl fmt::Display for Expression {

write!(f, "")
}
Expression::CastAs(cast_as) => {
write!(f, "{}", cast_as)
},
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions ast/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,4 +231,16 @@ mod tests {

assert!(matches!(if_statement.condition, Expression::Literal(Literal::Bool(_))));
}

#[test]
fn test_cast_as() {
let cast_as_expression = CastAs {
expr: Box::new(Expression::Literal(Literal::Integer(IntegerLiteral::I32(10)))),
cast_as: TokenKind::Float,
span: Span::default(),
loc: Location::default(),
};

assert_eq!(cast_as_expression.to_string(), "10 as float");
}
}
1 change: 1 addition & 0 deletions ast/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ impl fmt::Display for TokenKind {
Self::Float => write!(f, "float"),
Self::Double => write!(f, "double"),
Self::Void => write!(f, "void"),
Self::As => write!(f, "as"),
Self::Literal(literal) => match literal {
Literal::Integer(integer_literal) => match integer_literal {
crate::ast::IntegerLiteral::I8(value) => write!(f, "{}", value),
Expand Down
16 changes: 13 additions & 3 deletions compiler/src/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ impl Compiler {
Expression::StructFieldAccess(struct_field_access) => {
self.compile_struct_field_access(scope, *struct_field_access)
}
Expression::CastAs(cast_as) => todo!(),
}
}

Expand Down Expand Up @@ -234,16 +235,25 @@ impl Compiler {
}

fn compile_assignment(&mut self, scope: ScopeRef, assignment: Assignment) -> *mut gcc_jit_rvalue {
let (lvalue, _) = self.access_identifier_values(Rc::clone(&scope), assignment.identifier);
let (lvalue, rvalue) = self.access_identifier_values(Rc::clone(&scope), assignment.identifier);

let block_func = self.block_func_ref.lock().unwrap();
if let Some(block) = block_func.block {
drop(block_func);

let rvalue = self.compile_expression(scope, assignment.expr);
let target_type = unsafe { gcc_jit_rvalue_get_type(rvalue) };
let new_rvalue = self.compile_expression(scope, assignment.expr);
let casted_rvalue = unsafe {
gcc_jit_context_new_cast(
self.context,
self.gccjit_location(assignment.loc.clone()),
new_rvalue,
target_type,
)
};

unsafe {
gcc_jit_block_add_assignment(block, self.gccjit_location(assignment.loc.clone()), lvalue, rvalue);
gcc_jit_block_add_assignment(block, self.gccjit_location(assignment.loc.clone()), lvalue, casted_rvalue);
};

return rvalue;
Expand Down
13 changes: 1 addition & 12 deletions examples/main.cy
Original file line number Diff line number Diff line change
@@ -1,12 +1 @@
import io;
import memory;

pub fn main() {
printf("Program started.\n");

#a: *void = Memory.malloc(32);
*a = 10;
Memory.free(a);

printf("Program end.\n");
}
#a: string[2][2] = "";
67 changes: 36 additions & 31 deletions parser/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,37 +54,37 @@ impl<'a> Parser<'a> {
self.next_token();
return Ok(TokenKind::AddressOf(Box::new(self.parse_type_token()?)));
}
TokenKind::Identifier { name: type_name } => {
TokenKind::UserDefinedType(Identifier {
name: type_name.clone(),
span: self.current_token.span.clone(),
loc: self.current_location(),
})
},
_ => return
Err(CompileTimeError {
location,
etype: ParserErrorType::InvalidTypeToken(token_kind.clone()),
file_name: Some(self.lexer.file_name.clone()),
code_raw: Some(self
.lexer
.select(self.current_token.span.start..self.current_token.span.end)),
verbose: None,
caret: true,
TokenKind::Identifier { name: type_name } => TokenKind::UserDefinedType(Identifier {
name: type_name.clone(),
span: self.current_token.span.clone(),
loc: self.current_location(),
}),
_ => {
return Err(CompileTimeError {
location,
etype: ParserErrorType::InvalidTypeToken(token_kind.clone()),
file_name: Some(self.lexer.file_name.clone()),
code_raw: Some(
self.lexer
.select(self.current_token.span.start..self.current_token.span.end),
),
verbose: None,
caret: true,
})
}
},
};

self.next_token(); // consume the data type

// Check for array data type
if self.current_token_is(TokenKind::LeftBracket) {
if self.peek_token_is(TokenKind::LeftBracket) {
self.next_token(); // consume the data type

let mut dimensions: Vec<Option<TokenKind>> = Vec::new();

while self.current_token_is(TokenKind::LeftBracket) {
let mut capacity: Option<TokenKind> = None;

self.next_token();
self.next_token(); // consume left bracket

if let TokenKind::Literal(_) = self.current_token.kind.clone() {
capacity = Some(self.current_token.kind.clone());
Expand Down Expand Up @@ -112,16 +112,21 @@ impl<'a> Parser<'a> {
TokenKind::Inline => VisType::Inline,
TokenKind::Extern => VisType::Extern,
TokenKind::Pub => VisType::Pub,
_ => return Err(CompileTimeError {
location: self.current_location(),
etype: ParserErrorType::InvalidToken(self.current_token.kind.clone()),
file_name: Some(self.lexer.file_name.clone()),
code_raw: Some(self
.lexer
.select(self.current_token.span.start..self.current_token.span.end)),
verbose: Some(String::from("Expected one of: 'inline', 'extern', 'pub' as function visibility.")),
caret: true,
}),
_ => {
return Err(CompileTimeError {
location: self.current_location(),
etype: ParserErrorType::InvalidToken(self.current_token.kind.clone()),
file_name: Some(self.lexer.file_name.clone()),
code_raw: Some(
self.lexer
.select(self.current_token.span.start..self.current_token.span.end),
),
verbose: Some(String::from(
"Expected one of: 'inline', 'extern', 'pub' as function visibility.",
)),
caret: true,
})
}
};
self.next_token(); // consume vis_type token
Ok(vis_type)
Expand Down
36 changes: 30 additions & 6 deletions parser/src/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl<'a> Parser<'a> {
}
TokenKind::Null => Expression::Literal(Literal::Null),
token_kind @ TokenKind::Increment | token_kind @ TokenKind::Decrement => {
let ty = match token_kind {
let unary_operator_type = match token_kind {
TokenKind::Increment => UnaryOperatorType::PreIncrement,
TokenKind::Decrement => UnaryOperatorType::PreDecrement,
_ => {
Expand All @@ -79,7 +79,7 @@ impl<'a> Parser<'a> {
loc: self.current_location(),
}
},
ty,
ty: unary_operator_type,
span: Span {
start: span.start,
end: self.current_token.span.end,
Expand All @@ -105,6 +105,7 @@ impl<'a> Parser<'a> {
loc: self.current_location(),
};


if self.peek_token_is(TokenKind::Increment) {
self.next_token();
Expression::UnaryOperator(UnaryOperator {
Expand Down Expand Up @@ -150,7 +151,9 @@ impl<'a> Parser<'a> {

Expression::Literal(Literal::Bool(BoolLiteral { raw, span }))
}
TokenKind::Literal(value) => Expression::Literal(value.clone()),
TokenKind::Literal(value) => {
Expression::Literal(value.clone())
}
TokenKind::Minus | TokenKind::Bang => {
let start = self.current_token.span.start;
let prefix_operator = self.current_token.clone();
Expand Down Expand Up @@ -202,6 +205,27 @@ impl<'a> Parser<'a> {
left: Expression,
left_start: usize,
) -> Option<Result<Expression, ParseError>> {
if self.peek_token_is(TokenKind::As) {
self.next_token(); // consume left
self.next_token(); // consume as token

match self.parse_type_token() { // ANCHOR
Ok(cast_as) => {
self.next_token();
return Some(Ok(Expression::CastAs(CastAs {
expr: Box::new(left),
cast_as,
span: Span {
start: left_start,
end: self.current_token.span.end.clone(),
},
loc: self.current_location(),
})));
}
Err(err) => return Some(Err(err)),
}
}

match &self.peek_token.kind {
TokenKind::Plus
| TokenKind::Minus
Expand Down Expand Up @@ -334,7 +358,7 @@ impl<'a> Parser<'a> {
match left {
Expression::Identifier(identifier) => {
self.next_token();

if !self.current_token_is(TokenKind::Semicolon) {
return Err(CompileTimeError {
location: self.current_location(),
Expand Down Expand Up @@ -392,7 +416,7 @@ impl<'a> Parser<'a> {
let start = self.current_token.span.start.clone();

let mut chains: Vec<FieldAccessOrMethodCall> = Vec::new();
self.next_token();
self.next_token();
self.expect_current(TokenKind::Dot)?;

loop {
Expand Down Expand Up @@ -429,7 +453,7 @@ impl<'a> Parser<'a> {
code_raw: Some(self.lexer.select(start..self.current_token.span.end)),
verbose: None,
caret: true,
})
});
}

let method_call = FuncCall {
Expand Down
6 changes: 4 additions & 2 deletions parser/src/precedences.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use core::fmt;

use ast::token::TokenKind;
use core::fmt;

#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
pub enum Precedence {
Expand All @@ -12,10 +11,12 @@ pub enum Precedence {
Prefix, // -X or !X
Call, // my_function(x)
Index, // array[index]
Cast, // Type conversion
}

pub fn token_precedence_of(token_kind: TokenKind) -> Precedence {
match token_kind {
TokenKind::As => Precedence::Cast,
TokenKind::Equal => Precedence::Equals,
TokenKind::NotEqual => Precedence::Equals,
TokenKind::LessThan => Precedence::LessGreater,
Expand Down Expand Up @@ -44,6 +45,7 @@ impl fmt::Display for Precedence {
Precedence::Prefix => write!(f, "prefix"),
Precedence::Call => write!(f, "call"),
Precedence::Index => write!(f, "index"),
Precedence::Cast => write!(f, "cast"),
}
}
}
Expand Down
11 changes: 6 additions & 5 deletions parser/src/statements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ impl<'a> Parser<'a> {
let loc = self.current_location();
let start = self.current_token.span.start;

let vis_type = self.parse_vis_type(self.current_token.clone()).unwrap_or(VisType::Internal);
let vis_type = self
.parse_vis_type(self.current_token.clone())
.unwrap_or(VisType::Internal);
if vis_type == VisType::Inline {
compiler_error!("Inline vis type is invalid for structs. It only can be used for funcs.")
}
Expand Down Expand Up @@ -625,12 +627,12 @@ impl<'a> Parser<'a> {
loc: self.current_location(),
}));
}

self.expect_current(TokenKind::Assign)?;

let (expr, span) = self.parse_expression(Precedence::Lowest)?;
self.next_token();

if !self.peek_token_is(TokenKind::Semicolon) {
if !self.current_token_is(TokenKind::Semicolon) {
return Err(CompileTimeError {
location: self.current_location(),
etype: ParserErrorType::MissingSemicolon,
Expand All @@ -640,7 +642,6 @@ impl<'a> Parser<'a> {
caret: true,
});
}
self.next_token();

Ok(Statement::Variable(Variable {
name,
Expand Down Expand Up @@ -723,7 +724,7 @@ impl<'a> Parser<'a> {
}));
} else if self.current_token_is(TokenKind::As) {
self.next_token();

// parse renamed func decl
let renamed_as = match self.current_token.kind.clone() {
TokenKind::Identifier { name } => name,
Expand Down
Binary file modified stdlib/io.o
Binary file not shown.
Binary file modified stdlib/memory.o
Binary file not shown.

0 comments on commit a8a285f

Please sign in to comment.