Skip to content

Commit

Permalink
Updated JSPD.
Browse files Browse the repository at this point in the history
  • Loading branch information
facundo-villa committed Feb 19, 2024
1 parent 7668ff7 commit 4f5d8cd
Show file tree
Hide file tree
Showing 6 changed files with 249 additions and 162 deletions.
176 changes: 119 additions & 57 deletions jspd/src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ impl Deref for NodeReference {
}

pub(super) fn lex(node: &parser::Node, parser_program: &parser::ProgramState) -> Result<NodeReference, LexError> {
let mut program = ProgramState {
types: HashMap::new(),
};
return lex_parsed_node(None, None, node, parser_program,);
}

return lex_parsed_node(None, node, parser_program, &mut program);
pub(super) fn lex_with_root(root: NodeReference, node: &parser::Node, parser_program: &parser::ProgramState) -> Result<NodeReference, LexError> {
return lex_parsed_node(Some(root.clone()), Some(Rc::downgrade(&root.0)), node, parser_program,);
}

#[derive(Clone, Debug)]
Expand All @@ -52,7 +52,7 @@ impl Node {
pub fn scope(name: String, children: Vec<NodeReference>) -> NodeReference {
Self::internal_new(Node {
parent: None,
node: Nodes::Scope{ name, children },
node: Nodes::Scope{ name, children, program_state: ProgramState { types: HashMap::new(), members: HashMap::new() } },
})
}

Expand Down Expand Up @@ -107,6 +107,19 @@ impl Node {
})
}

pub fn binding(name: String, set: u32, binding: u32, read: bool, write: bool) -> NodeReference {
Self::internal_new(Node {
parent: None,
node: Nodes::Binding {
name,
set,
binding,
read,
write,
},
})
}

pub fn new(node: Nodes) -> Node {
Node {
parent: None,
Expand Down Expand Up @@ -194,12 +207,42 @@ impl Node {
}
}
}

pub fn node_mut(&mut self) -> &mut Nodes {
&mut self.node
}

pub fn get_program_state(&self) -> Option<&ProgramState> {
match &self.node {
Nodes::Scope { program_state, .. } => {
Some(program_state)
}
_ => {
None
}
}
}

pub fn get_program_state_mut(&mut self) -> Option<&mut ProgramState> {
match &mut self.node {
Nodes::Scope { program_state, .. } => {
Some(program_state)
}
_ => {
None
}
}
}
}

#[derive(Clone, Debug,)]
pub enum Nodes {
Null,
Scope{ name: String, children: Vec<NodeReference> },
Scope {
name: String,
children: Vec<NodeReference>,
program_state: ProgramState,
},
Struct {
name: String,
template: Option<NodeReference>,
Expand All @@ -220,7 +263,14 @@ pub enum Nodes {
Expression(Expressions),
GLSL {
code: String,
}
},
Binding {
name: String,
set: u32,
binding: u32,
read: bool,
write: bool,
},
}

#[derive(Clone, Debug)]
Expand All @@ -241,8 +291,11 @@ pub enum Operators {

#[derive(Clone, Debug,)]
pub enum Expressions {
Member{ name: String },
Literal { value: String },
Member {
name: String,
source: Option<NodeReference>,
},
Literal { value: String, },
FunctionCall {
function: NodeReference,
name: String,
Expand All @@ -267,6 +320,9 @@ pub enum Expressions {
#[derive(Debug)]
pub(crate) enum LexError {
Undefined,
AccessingUndeclaredMember {
name: String,
},
NoSuchType{
type_name: String,
},
Expand All @@ -275,9 +331,10 @@ pub(crate) enum LexError {
type LexerReturn<'a> = Result<(Rc<Node>, std::slice::Iter<'a, String>), LexError>;
type Lexer<'a> = fn(std::slice::Iter<'a, String>, &'a parser::ProgramState) -> LexerReturn<'a>;

#[derive(Clone)]
#[derive(Clone, Debug)]
pub(crate) struct ProgramState {
pub(crate) types: HashMap<String, NodeReference>,
pub(crate) members: HashMap<String, NodeReference>,
}

/// Execute a list of lexers on a stream of tokens.
Expand All @@ -302,34 +359,34 @@ fn try_execute_lexers<'a>(lexers: &[Lexer<'a>], iterator: std::slice::Iter<'a, S
None
}

fn lex_parsed_node(parent_node: Option<ParentNodeReference>, parser_node: &parser::Node, parser_program: &parser::ProgramState, program: &mut ProgramState) -> Result<NodeReference, LexError> {
fn lex_parsed_node(scope: Option<NodeReference>, parent_node: Option<ParentNodeReference>, parser_node: &parser::Node, parser_program: &parser::ProgramState) -> Result<NodeReference, LexError> {
let node = match &parser_node.node {
parser::Nodes::Scope{ name, children } => {
let this = Node::scope(name.clone(), Vec::new());

let ch = children.iter().map(|child| {
lex_parsed_node(Some(Rc::downgrade(&this.0)), child, parser_program, program)
lex_parsed_node(Some(this.clone()), Some(Rc::downgrade(&this.0)), child, parser_program,)
}).collect::<Result<Vec<NodeReference>, LexError>>()?;

RefCell::borrow_mut(&this).add_children(ch);

this
}
parser::Nodes::Struct { name, fields } => {
if let Some(n) = program.types.get(name) { // If the type already exists, return it.
if let Some(n) = RefCell::borrow(&scope.clone().ok_or(LexError::Undefined)?.0).get_program_state().ok_or(LexError::Undefined)?.types.get(name) { // If the type already exists, return it.
return Ok(n.clone());
}

let this = Node::r#struct(name.clone(), Vec::new());

let ch = fields.iter().map(|field| {
lex_parsed_node(Some(Rc::downgrade(&this.0)), &field, parser_program, program)
lex_parsed_node(scope.clone(), Some(Rc::downgrade(&this.0)), &field, parser_program,)
}).collect::<Result<Vec<NodeReference>, LexError>>()?;

RefCell::borrow_mut(&this).add_children(ch);

program.types.insert(name.clone(), this.clone());
program.types.insert(format!("{}*", name.clone()), this.clone());
RefCell::borrow_mut(&scope.clone().ok_or(LexError::Undefined)?.0).get_program_state_mut().ok_or(LexError::Undefined)?.types.insert(name.clone(), this.clone());
RefCell::borrow_mut(&scope.clone().ok_or(LexError::Undefined)?.0).get_program_state_mut().ok_or(LexError::Undefined)?.types.insert(format!("{}*", name.clone()), this.clone());

this
}
Expand All @@ -339,7 +396,7 @@ fn lex_parsed_node(parent_node: Option<ParentNodeReference>, parser_node: &parse

let outer_type_name = s.next().ok_or(LexError::Undefined)?;

let outer_type = lex_parsed_node(None, parser_program.types.get(outer_type_name).ok_or(LexError::NoSuchType{ type_name: outer_type_name.to_string() })?, parser_program, program)?;
let outer_type = lex_parsed_node(scope.clone(), None, parser_program.types.get(outer_type_name).ok_or(LexError::NoSuchType{ type_name: outer_type_name.to_string() })?, parser_program,)?;

let inner_type_name = s.next().ok_or(LexError::Undefined)?;

Expand All @@ -356,14 +413,14 @@ fn lex_parsed_node(parent_node: Option<ParentNodeReference>, parser_node: &parse
}
);

program.types.insert(format!("{}*", stripped), x.clone());
RefCell::borrow_mut(&scope.clone().ok_or(LexError::Undefined)?.0).get_program_state_mut().ok_or(LexError::Undefined)?.types.insert(format!("{}*", stripped), x.clone());

x
} else {
lex_parsed_node(parent_node.clone(), parser_program.types.get(inner_type_name).ok_or(LexError::NoSuchType{ type_name: inner_type_name.to_string() })?, parser_program, program)?
lex_parsed_node(scope.clone(), parent_node.clone(), parser_program.types.get(inner_type_name).ok_or(LexError::NoSuchType{ type_name: inner_type_name.to_string() })?, parser_program,)?
};

if let Some(n) = program.types.get(r#type) { // If the type already exists, return it.
if let Some(n) = RefCell::borrow_mut(&scope.clone().ok_or(LexError::Undefined)?.0).get_program_state_mut().ok_or(LexError::Undefined)?.types.get(r#type) { // If the type already exists, return it.
return Ok(n.clone());
}

Expand All @@ -385,24 +442,24 @@ fn lex_parsed_node(parent_node: Option<ParentNodeReference>, parser_node: &parse

let node = Node::internal_new(struct_node);

program.types.insert(r#type.clone(), node.clone());
RefCell::borrow_mut(&scope.clone().ok_or(LexError::Undefined)?.0).get_program_state_mut().ok_or(LexError::Undefined)?.types.insert(r#type.clone(), node.clone());

node
} else {
let t = parser_program.types.get(r#type.as_str()).ok_or(LexError::NoSuchType{ type_name: r#type.clone() })?;
lex_parsed_node(None, t, parser_program, program)?
lex_parsed_node(scope, None, t, parser_program,)?
};

Node::member(name.clone(), t,)
}
parser::Nodes::Function { name, return_type, statements, raw, .. } => {
let t = parser_program.types.get(return_type.as_str()).ok_or(LexError::NoSuchType{ type_name: return_type.clone() })?;
let t = lex_parsed_node(None, t, parser_program, program)?;
let t = lex_parsed_node(scope.clone(), None, t, parser_program,)?;

let this = Node::function(parent_node.clone(), name.clone(), Vec::new(), t, Vec::new(), raw.clone(),);

let st = statements.iter().map(|statement| {
lex_parsed_node(Some(Rc::downgrade(&this.0)), statement, parser_program, program)
lex_parsed_node(scope.clone(), Some(Rc::downgrade(&this.0)), statement, parser_program,)
}).collect::<Result<Vec<NodeReference>, LexError>>()?;

match RefCell::borrow_mut(&this).node {
Expand All @@ -418,51 +475,56 @@ fn lex_parsed_node(parent_node: Option<ParentNodeReference>, parser_node: &parse
match expression {
parser::Expressions::Accessor{ left, right } => {
Node::expression(Expressions::Accessor {
left: lex_parsed_node(None, left, parser_program, program)?,
right: lex_parsed_node(None, right, parser_program, program)?,
})
left: lex_parsed_node(scope.clone(), None, left, parser_program,)?,
right: lex_parsed_node(scope.clone(), None, right, parser_program,)?,
})
}
parser::Expressions::Member{ name } => {
Node::expression(Expressions::Member {
name: name.clone(),
})
source: Some(RefCell::borrow(&scope.clone().ok_or(LexError::Undefined)?.0).get_program_state().ok_or(LexError::Undefined)?.members.get(name).ok_or(LexError::AccessingUndeclaredMember{ name: name.clone() })?.clone()),
name: name.clone(),
})
}
parser::Expressions::Literal{ value } => {
Node::expression(Expressions::Literal {
value: value.clone(),
})
value: value.clone(),
})
}
parser::Expressions::FunctionCall{ name, parameters } => {
let t = parser_program.types.get(name.as_str()).ok_or(LexError::NoSuchType{ type_name: name.clone() })?;
let function = lex_parsed_node(None, t, parser_program, program)?;
let function = lex_parsed_node(scope.clone(), None, t, parser_program,)?;
Node::expression(Expressions::FunctionCall {
function,
name: name.clone(),
parameters: parameters.iter().map(|e| lex_parsed_node(None, e, parser_program, program).unwrap()).collect(),
parameters: parameters.iter().map(|e| lex_parsed_node(scope.clone(), None, e, parser_program,).unwrap()).collect(),
})
}
parser::Expressions::Operator{ name, left, right } => {
Node::expression(Expressions::Operator {
operator: match name.as_str() {
"+" => Operators::Plus,
"-" => Operators::Minus,
"*" => Operators::Multiply,
"/" => Operators::Divide,
"%" => Operators::Modulo,
"=" => Operators::Assignment,
"==" => Operators::Equality,
_ => { panic!("Invalid operator") }
},
left: lex_parsed_node(None, left, parser_program, program)?,
right: lex_parsed_node(None, right, parser_program, program)?,
})
operator: match name.as_str() {
"+" => Operators::Plus,
"-" => Operators::Minus,
"*" => Operators::Multiply,
"/" => Operators::Divide,
"%" => Operators::Modulo,
"=" => Operators::Assignment,
"==" => Operators::Equality,
_ => { panic!("Invalid operator") }
},
left: lex_parsed_node(scope.clone(), None, left, parser_program,)?,
right: lex_parsed_node(scope.clone(), None, right, parser_program,)?,
})
}
parser::Expressions::VariableDeclaration{ name, r#type } => {
Node::expression(Expressions::VariableDeclaration {
name: name.clone(),
// r#type: lex_parsed_node(&r#type, parser_program, program)?,
r#type: r#type.clone(),
})
let this = Node::expression(Expressions::VariableDeclaration {
name: name.clone(),
// r#type: lex_parsed_node(&r#type, parser_program, program)?,
r#type: r#type.clone(),
});

RefCell::borrow_mut(&scope.clone().ok_or(LexError::Undefined)?.0).get_program_state_mut().ok_or(LexError::Undefined)?.members.insert(name.clone(), this.clone());

this
}
}
}
Expand Down Expand Up @@ -490,8 +552,8 @@ mod tests {
fn lex_function() {
let source = "
main: fn () -> void {
position: vec4f = vec4(0.0, 0.0, 0.0, 1.0);
gl_Position = position;
position: vec4f = vec4f(0.0, 0.0, 0.0, 1.0);
position = position;
}";

let tokens = tokenizer::tokenize(source).expect("Failed to tokenize");
Expand Down Expand Up @@ -534,7 +596,7 @@ main: fn () -> void {

match constructor.node() {
Nodes::Expression(Expressions::FunctionCall{ name, parameters, .. }) => {
assert_eq!(name, "vec4");
assert_eq!(name, "vec4f");
assert_eq!(parameters.len(), 4);
}
_ => { panic!("Expected expression"); }
Expand Down Expand Up @@ -562,7 +624,7 @@ color: In<vec4f>;
let node = node.borrow();

match node.node() {
Nodes::Scope{ name, children } => {
Nodes::Scope{ name, children, .. } => {
assert_eq!(name, "root");

let color = children[0].borrow();
Expand Down Expand Up @@ -617,7 +679,7 @@ color: In<vec4f>;
let node = node.borrow();

match node.node() {
Nodes::Scope{ name, children } => {
Nodes::Scope{ name, children, .. } => {
assert_eq!(name, "root");

let vertex = children[0].borrow();
Expand Down
17 changes: 14 additions & 3 deletions jspd/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,25 @@ pub use lexer::Nodes;

pub use crate::lexer::NodeReference;

pub fn compile_to_jspd(source: &str) -> Result<NodeReference, CompilationError> {
/// Compiles a BESL source code string into a JSPD.
///
/// # Arguments
///
/// * `source` - The source code to compile.
/// * `parent` - An optional reference to a parent Scope node where the source code will be compiled into.
pub fn compile_to_jspd(source: &str, parent: Option<NodeReference>) -> Result<NodeReference, CompilationError> {
if source.split_whitespace().next() == None {
return Ok(lexer::Node::scope("".to_string(), Vec::new()));
}

let tokens = tokenizer::tokenize(source).map_err(|_e| CompilationError::Undefined)?;
let (parser_root_node, parser_program) = parser::parse(tokens).map_err(|_e| CompilationError::Undefined)?;
let jspd = lexer::lex(&parser_root_node, &parser_program).map_err(|_e| CompilationError::Undefined)?;

let jspd = if let Some(parent) = parent {
lexer::lex_with_root(parent, &parser_root_node, &parser_program).map_err(|_e| CompilationError::Undefined)?
} else {
lexer::lex(&parser_root_node, &parser_program).map_err(|_e| CompilationError::Undefined)?
};

Ok(jspd)
}
Expand Down Expand Up @@ -201,7 +212,7 @@ mod tests {

let jspd = jspd.borrow();

if let lexer::Nodes::Scope { name, children } = jspd.node() {
if let lexer::Nodes::Scope { name, children, .. } = jspd.node() {
assert_eq!(name, "root");
assert!(children.len() > 1);
} else {
Expand Down
Loading

0 comments on commit 4f5d8cd

Please sign in to comment.