Skip to content

Commit

Permalink
Broke up code into files, expanded grammar
Browse files Browse the repository at this point in the history
And basic parser test
  • Loading branch information
mirdaki-ms committed Oct 12, 2021
1 parent cc14329 commit b91e1c0
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 56 deletions.
78 changes: 70 additions & 8 deletions DESIGN.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Design of the Force

WIP

## Keyword Mapping

- False
- Amazing, every word of what you just said is wrong
- Oh, not good
Expand Down Expand Up @@ -59,9 +63,9 @@
- DeclareMethod
- What is thy bidding, my master
- **This is where the fun begins**
- NonVoidMethod
- All right that's pretty much nowhere
- MethodArguments
- NotVoidMethod
- It's a trap
- MethodArgument
- Now that’s a name I have not heard in a long time, a long time
- Return
- There is nothing for me here now
Expand All @@ -78,15 +82,15 @@
- You saved me
- As you wish
- **Many Bothans died to bring us this information**
- DeclareInt
- DeclareFloat
- Yoda, you seek Yoda
- DeclareString
-
- Size matters not
- DeclareBool
- I am the senate
- SetInitialValue
- The maker!
- Whoosa are youssa
- **Whoosa are youssa**
- BeginMain
- **Do it**
- This is where the fun begins
Expand All @@ -96,10 +100,10 @@
- Use the Force
- What is meessa saying
- **The Sacred Texts!**
- ReadInteger
- ReadFloat
- Looking, found someone I would say you have
- ReadString
-
- Now this is pod racing
- AssignVariable
- What a piece of junk
- SetValue
Expand Down Expand Up @@ -131,3 +135,61 @@ Thinhs we must use
- I’ll try spinning, thats a good trick
- Now this is pod racing
- Size matters not

## Example

With out the keywords

```force
DeclareMethod name
# void
EndMethodDeclaration
DeclareMethod name
MethodArgument firstArg
MethodArgument secondArg
NonVoidMethod
# Stuff
Return value
EndMethodDeclaration
BeginMain
DeclareFloat name
SetInitialValue value
AssignVariable name
SetValue firstOperand
+ secondOperand
/ thirdOperand
EndAssignVariable
AssignVariable name
SetValue firstOperand
or secondOperand
EndAssignVariable
AssignVariableFromMethodCall name
CallMethod name
EndAssignVariable
AssignVariableFromMethodCall name
CallMethod ReadString
EndAssignVariable
If value
# Stuff
Else
# Stuff
EndIf
While value
# Stuff
EndWhile
For intValueExpre # Auto increments a value?
# Stuff
EndFor
EndMain
```
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright © 2021 Matthew Booe
Copyright © 2021 The Force Collaborators

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
4 changes: 4 additions & 0 deletions src/ast.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Node {
Print(String)
}
19 changes: 15 additions & 4 deletions src/grammar.pest
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Program = _{ SOI ~ Main ~ EOI }
Program = _{ SOI ~ Method* ~ Main ~ EOI }

Main = { "Do it" ~ "The Sacred Texts!" ~ String ~ "May The Force be with you" }
Method = { VoidMethod | NonVoidMethod }

VoidMethod = { DeclareMethod ~ MethodArgument* ~ Statment ~ EndMethodDeclaration }

NonVoidMethod = {DeclareMethod ~ MethodArgument* ~ NotVoidMethod ~ Statment* ~ Return ~ EndMethodDeclaration }

Main = { BeginMain ~ Print ~ String ~ EndMain }

Statment = { "TEST" }

String = @{ "\"" ~ Inner ~ "\"" }
Inner = @{ (!("\"" | "\\") ~ ANY)* ~ (Escape ~ Inner)? }
Expand All @@ -9,7 +17,10 @@ Escape = @{ "\\" ~ ("\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" ) }
WHITESPACE = _{ " " | "\t" | "\n" }

BeginMain = _{ "Do it" }

EndMain = _{ "May The Force be with you" }

Print = _{ "The Sacred Texts!" }
DeclareMethod = _{ "This is where the fun begins" }
MethodArgument = _{ "Now that’s a name I have not heard in a long time, a long time" }
NotVoidMethod = _{ "It's a trap" }
Return = _{ "You’re all clear kid, let's blow this thing and go home" }
EndMethodDeclaration = _{ "It is clear to me the Republic no longer functions" }
7 changes: 7 additions & 0 deletions src/interpreter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use crate::ast::Node;

pub fn evaluate(ast: &Node) {
match ast {
Node::Print(x) => println!("{}", x),
}
}
48 changes: 5 additions & 43 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,13 @@
extern crate pest;
extern crate pest_derive;

use pest::Parser;

#[derive(Debug)]
pub enum Node {
Print(String)
}

#[derive(pest_derive::Parser)]
#[grammar = "grammar.pest"]
struct ForceParser;

fn parse(source: &str) -> Result<Vec<Node>, pest::error::Error<Rule>> {
let mut ast = vec![];
let pairs = ForceParser::parse(Rule::Program, source)?;
for pair in pairs {
if let Rule::Main = pair.as_rule() {
ast.push(build_ast(pair));
}
}
Ok(ast)
}

fn build_ast(pair: pest::iterators::Pair<Rule>) -> Node {
match pair.as_rule() {
Rule::Main => {
let mut pair = pair.into_inner();
let string = pair.next().unwrap();
Node::Print(string.as_span().as_str().to_string())
}
unknown => panic!("Unknown expr: {:?}", unknown),
}
}

fn evaluate(ast: &Node) {
match ast {
Node::Print(x) => println!("{}", x),
}
}
mod ast;
mod parser;
mod interpreter;

fn main() {
let source = r#"
Do it
The Sacred Texts! "Hello there"
May The Force be with you
"#;
let ast = parse(source);
evaluate(ast.unwrap().first().unwrap());
let ast = parser::parse(source);
interpreter::evaluate(ast.unwrap().first().unwrap());
}
54 changes: 54 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
extern crate pest;
extern crate pest_derive;

use pest::Parser;

use crate::ast::Node;

#[derive(pest_derive::Parser)]
#[grammar = "grammar.pest"]
struct ForceParser;

pub fn parse(source: &str) -> Result<Vec<Node>, pest::error::Error<Rule>> {
let mut ast = vec![];
let pairs = ForceParser::parse(Rule::Program, source)?;
for pair in pairs {
if let Rule::Main = pair.as_rule() {
ast.push(build_ast(pair));
}
}
Ok(ast)
}

fn build_ast(pair: pest::iterators::Pair<Rule>) -> Node {
match pair.as_rule() {
Rule::Main => {
let mut pair = pair.into_inner();
let string = pair.next().unwrap();
Node::Print(string.as_span().as_str().to_string())
}
unknown => panic!("Unknown expr: {:?}", unknown),
}
}

#[cfg(test)]
mod tests {
use super::*;

// Parser tests
#[test]
fn hello_there() {
let source = r#"
Do it
The Sacred Texts! "Hello there"
May The Force be with you
"#;
let hello_there = parse(source);
assert!(hello_there.is_ok());

assert_eq!(
hello_there.clone().unwrap(),
vec![Node::Print("\"Hello there\"".to_string())]
);
}
}

0 comments on commit b91e1c0

Please sign in to comment.