working transpiler
This commit is contained in:
+1
-1
@@ -14,5 +14,5 @@ lsp-types = "0.97.0"
|
|||||||
zip = "2.1.3"
|
zip = "2.1.3"
|
||||||
dirs = "5.0.1"
|
dirs = "5.0.1"
|
||||||
pest = "2"
|
pest = "2"
|
||||||
pest_derive = "2"
|
pest_derive = "2.1"
|
||||||
clap = "3"
|
clap = "3"
|
||||||
+16
-16
@@ -2,7 +2,7 @@ use std::{fs, path::Path, process::Command};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
transpiler::{State, Transpiler},
|
transpiler::{State, Transpiler},
|
||||||
utils::{Problem, ProblemCap, ProblemType, Variables},
|
utils::{Problem, ProblemCap, ProblemType},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn transpile(input_file: String, output_file: String, is_main: bool) -> u8 {
|
pub fn transpile(input_file: String, output_file: String, is_main: bool) -> u8 {
|
||||||
@@ -10,23 +10,23 @@ pub fn transpile(input_file: String, output_file: String, is_main: bool) -> u8 {
|
|||||||
let mut trsp = Transpiler {
|
let mut trsp = Transpiler {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let mut vars = Variables::new();
|
|
||||||
if let Ok(file_contents) = fs::read_to_string(input_file) {
|
if let Ok(file_contents) = fs::read_to_string(input_file) {
|
||||||
let mut output_code = trsp.transpile(file_contents, 0, &mut vars);
|
let output_code = trsp.transpile_code(file_contents, 0);
|
||||||
|
println!("{output_code}");
|
||||||
if is_main {
|
if is_main {
|
||||||
output_code += "fn main() {";
|
// output_code += "fn main() {";
|
||||||
output_code += vars
|
// output_code += vars
|
||||||
.get_var(
|
// .get_var(
|
||||||
"main".to_string(),
|
// "main".to_string(),
|
||||||
&mut trsp,
|
// &mut trsp,
|
||||||
State {
|
// State {
|
||||||
line: 0,
|
// line: 0,
|
||||||
column: 0,
|
// column: 0,
|
||||||
file: None,
|
// file: None,
|
||||||
},
|
// },
|
||||||
)
|
// )
|
||||||
.as_str();
|
// .as_str();
|
||||||
output_code += "();}";
|
// output_code += "();}";
|
||||||
}
|
}
|
||||||
if let Ok(_) = fs::write(Path::new("build").join(output_file), output_code) {}
|
if let Ok(_) = fs::write(Path::new("build").join(output_file), output_code) {}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+1
-1
@@ -1,9 +1,9 @@
|
|||||||
use std::{fs, process};
|
use std::{fs, process};
|
||||||
|
|
||||||
mod compiler;
|
mod compiler;
|
||||||
mod parser;
|
|
||||||
mod transpiler;
|
mod transpiler;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
use compiler::{compile_rust, transpile};
|
use compiler::{compile_rust, transpile};
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
use pest::Parser;
|
|
||||||
use pest_derive::Parser;
|
|
||||||
|
|
||||||
#[derive(Parser)]
|
|
||||||
#[grammar = "wyst.pest"]
|
|
||||||
pub struct WystParser;
|
|
||||||
|
|
||||||
pub fn parse(input: String, rule: Rule) {
|
|
||||||
match WystParser::parse(rule, &input) {
|
|
||||||
Ok(parsed) => {
|
|
||||||
for pair in parsed {
|
|
||||||
println!("---------START--------");
|
|
||||||
println!("{:?}", pair);
|
|
||||||
println!("---------END--------");
|
|
||||||
}
|
|
||||||
// println!("{:#?}", parsed);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
println!("Ok: {}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+70
-69
@@ -1,9 +1,14 @@
|
|||||||
use crate::{
|
use pest::iterators::{Pair, Pairs};
|
||||||
parser::{self, Rule},
|
use crate::utils::{ProblemCap};
|
||||||
utils::{ProblemCap, Variables},
|
|
||||||
};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
// The Parser
|
||||||
|
use pest::Parser;
|
||||||
|
use pest_derive::Parser;
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[grammar = "wyst.pest"]
|
||||||
|
pub struct WystParser;
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||||
pub struct State {
|
pub struct State {
|
||||||
pub line: u32,
|
pub line: u32,
|
||||||
@@ -13,7 +18,6 @@ pub struct State {
|
|||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||||
pub struct Transpiler {
|
pub struct Transpiler {
|
||||||
pub matched_vars: Variables,
|
|
||||||
pub problems: Vec<ProblemCap>,
|
pub problems: Vec<ProblemCap>,
|
||||||
pub state: State,
|
pub state: State,
|
||||||
pub inject: Inject,
|
pub inject: Inject,
|
||||||
@@ -40,7 +44,6 @@ impl Default for Inject {
|
|||||||
impl Default for Transpiler {
|
impl Default for Transpiler {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Transpiler {
|
Transpiler {
|
||||||
matched_vars: Variables::new(),
|
|
||||||
inject: Inject::default(),
|
inject: Inject::default(),
|
||||||
problems: Vec::new(),
|
problems: Vec::new(),
|
||||||
state: State {
|
state: State {
|
||||||
@@ -52,74 +55,72 @@ impl Default for Transpiler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_indexable(pairs: Pairs<Rule>) -> Vec<Pair<Rule>> {
|
||||||
|
let mut arr: Vec<Pair<Rule>> = Vec::new();
|
||||||
|
for pair in pairs {arr.push(pair)}
|
||||||
|
arr
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
impl Transpiler {
|
impl Transpiler {
|
||||||
pub fn transpile(&mut self, code: String, indent: usize, vars: &mut Variables) -> String {
|
pub fn transpile_pairs(&mut self, pairs: Pairs<Rule>) -> String {
|
||||||
// args: code, vars, &mut self.state.clone(), self
|
|
||||||
let ast = parser::parse(code, Rule::top_expr);
|
|
||||||
let mut res = String::new();
|
let mut res = String::new();
|
||||||
|
for pair in pairs {
|
||||||
|
res+=self.transpile(pair).as_str();
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
pub fn transpile(&mut self, pair: Pair<Rule>) -> String {
|
||||||
|
let mut res = String::new();
|
||||||
|
let tokens = to_indexable(pair.clone().into_inner());
|
||||||
|
match pair.as_rule() {
|
||||||
|
Rule::func_def => {
|
||||||
|
res += format!("fn {}({}) -> {} {}", tokens[1].as_str(),
|
||||||
|
self.transpile_pairs(tokens[2].clone().into_inner()).as_str(),
|
||||||
|
tokens[0].as_str(),
|
||||||
|
self.transpile(tokens[3].clone())
|
||||||
|
).as_str();
|
||||||
|
}
|
||||||
|
Rule::var_def => {
|
||||||
|
res += format!("let mut {}: {}", tokens[1].as_str(), tokens[0].as_str()).as_str();
|
||||||
|
}
|
||||||
|
Rule::curly => {
|
||||||
|
res += "{";
|
||||||
|
res += &self.transpile_pairs(pair.clone().into_inner());
|
||||||
|
res += "}";
|
||||||
|
}
|
||||||
|
Rule::code_expr => {
|
||||||
|
res += &self.transpile_pairs(pair.clone().into_inner());
|
||||||
|
}
|
||||||
|
//TODO: use LibManager to manage the includes
|
||||||
|
Rule::include_global => {}
|
||||||
|
Rule::include => {}
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
res += " ";
|
||||||
|
res += pair.as_str();
|
||||||
|
res += " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
pub fn transpile_code(&mut self, code: String, indent: usize) -> String {
|
||||||
|
let mut res = String::new();
|
||||||
|
match WystParser::parse(Rule::top_expr, &code) {
|
||||||
|
Ok(parsed) => {
|
||||||
|
for pair in parsed {
|
||||||
|
res += self.transpile_pairs(pair.into_inner()).as_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
// println!("err: {}", e.line());
|
||||||
|
println!("{}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
if indent > 0 {
|
if indent > 0 {
|
||||||
res += " ".repeat(indent * 2).as_str();
|
res += " ".repeat(indent * 2).as_str();
|
||||||
}
|
}
|
||||||
// for a in ast {
|
|
||||||
// let astval = extract_ast(a.clone());
|
|
||||||
// if self.inject.inject {
|
|
||||||
// for val in astval {
|
|
||||||
// if val.contains("list_vx") {
|
|
||||||
// for (name, var) in vars.clone().iter_mut() {
|
|
||||||
// if self.inject.state.line > var.state.line
|
|
||||||
// || var.vtype != VariableType::Var
|
|
||||||
// {
|
|
||||||
// self.matched_vars.vars.insert(name.clone(), var.clone());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// match a {
|
|
||||||
// Ast::Variable(var_type, var_name) => {
|
|
||||||
// res += format!("let mut {}: {}", var_name, var_type).as_str();
|
|
||||||
// }
|
|
||||||
// Ast::Function(var_type, var_name, round, curly) => {
|
|
||||||
// res += format!(
|
|
||||||
// "fn {}({}) -> {} {}\n{}{}\n",
|
|
||||||
// var_name,
|
|
||||||
// round,
|
|
||||||
// var_type,
|
|
||||||
// "{",
|
|
||||||
// self.transpile(curly, indent + 1, &mut vars.clone()),
|
|
||||||
// "}"
|
|
||||||
// )
|
|
||||||
// .as_str();
|
|
||||||
// }
|
|
||||||
// Ast::Struct(name, curly) => {
|
|
||||||
// res += format!(
|
|
||||||
// "struct {} {}\n{}{}\n",
|
|
||||||
// name,
|
|
||||||
// "{",
|
|
||||||
// self.transpile(curly, indent + 1, &mut vars.clone()),
|
|
||||||
// "}"
|
|
||||||
// )
|
|
||||||
// .as_str()
|
|
||||||
// }
|
|
||||||
// Ast::Rust(rs) => {
|
|
||||||
// res += "{";
|
|
||||||
// res += rs.as_str();
|
|
||||||
// res += "}";
|
|
||||||
// }
|
|
||||||
// Ast::Single(x) => {
|
|
||||||
// println!("{:?}", x);
|
|
||||||
// let vals = extract_values(x);
|
|
||||||
// match vals.0 {
|
|
||||||
// 2 => res += vars.get_var(vals.1, self, vals.2).as_str(),
|
|
||||||
// 3 => res += format!("({})", vals.1).as_str(),
|
|
||||||
// 8 => res += vals.1.as_str(),
|
|
||||||
// _ => {
|
|
||||||
// res += vals.1.as_str();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
if indent > 0 {
|
if indent > 0 {
|
||||||
res += "\n";
|
res += "\n";
|
||||||
res += " ".repeat((indent - 1) * 2).as_str();
|
res += " ".repeat((indent - 1) * 2).as_str();
|
||||||
|
|||||||
-226
@@ -1,8 +1,5 @@
|
|||||||
use crate::transpiler::State;
|
use crate::transpiler::State;
|
||||||
use crate::transpiler::Transpiler;
|
|
||||||
use rand::Rng;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub enum ProblemType {
|
pub enum ProblemType {
|
||||||
@@ -23,226 +20,3 @@ pub struct Problem {
|
|||||||
pub problem_msg: String,
|
pub problem_msg: String,
|
||||||
pub state: State,
|
pub state: State,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
|
|
||||||
pub enum VariableType {
|
|
||||||
Var,
|
|
||||||
Func,
|
|
||||||
Keyword,
|
|
||||||
Struct,
|
|
||||||
Namespace,
|
|
||||||
Enum,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
||||||
pub struct Variable {
|
|
||||||
pub vtype: VariableType,
|
|
||||||
pub desc: String,
|
|
||||||
pub state: State,
|
|
||||||
pub params: Variables,
|
|
||||||
pub rname: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
||||||
pub struct Variables {
|
|
||||||
pub vars: HashMap<String, Variable>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Variables {
|
|
||||||
pub fn new() -> Variables {
|
|
||||||
Variables {
|
|
||||||
vars: HashMap::from([
|
|
||||||
(
|
|
||||||
"void".to_string(),
|
|
||||||
Variable {
|
|
||||||
vtype: VariableType::Keyword,
|
|
||||||
desc: "".to_string(),
|
|
||||||
state: State {
|
|
||||||
line: 0,
|
|
||||||
column: 0,
|
|
||||||
file: None,
|
|
||||||
},
|
|
||||||
params: Variables {
|
|
||||||
vars: HashMap::new(),
|
|
||||||
},
|
|
||||||
rname: "".to_string(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"println".to_string(),
|
|
||||||
Variable {
|
|
||||||
vtype: VariableType::Keyword,
|
|
||||||
desc: "".to_string(),
|
|
||||||
state: State {
|
|
||||||
line: 0,
|
|
||||||
column: 0,
|
|
||||||
file: None,
|
|
||||||
},
|
|
||||||
params: Variables {
|
|
||||||
vars: HashMap::new(),
|
|
||||||
},
|
|
||||||
rname: "println".to_string(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn new_var(&mut self, name: String, state: State, desc: String) -> String {
|
|
||||||
let rname = generate_varname();
|
|
||||||
self.vars.insert(
|
|
||||||
name,
|
|
||||||
Variable {
|
|
||||||
vtype: VariableType::Var,
|
|
||||||
desc,
|
|
||||||
state,
|
|
||||||
params: Variables {
|
|
||||||
vars: HashMap::new(),
|
|
||||||
},
|
|
||||||
rname: rname.clone(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
rname
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_namespace(&mut self, name: String, state: State, desc: String) -> String {
|
|
||||||
let rname = generate_varname();
|
|
||||||
self.vars.insert(
|
|
||||||
name,
|
|
||||||
Variable {
|
|
||||||
vtype: VariableType::Namespace,
|
|
||||||
desc,
|
|
||||||
state,
|
|
||||||
params: Variables {
|
|
||||||
vars: HashMap::new(),
|
|
||||||
},
|
|
||||||
rname: rname.clone(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
rname
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_struct(&mut self, name: String, state: State, desc: String) -> String {
|
|
||||||
let rname = generate_varname();
|
|
||||||
self.vars.insert(
|
|
||||||
name,
|
|
||||||
Variable {
|
|
||||||
vtype: VariableType::Struct,
|
|
||||||
desc,
|
|
||||||
state,
|
|
||||||
params: Variables {
|
|
||||||
vars: HashMap::new(),
|
|
||||||
},
|
|
||||||
rname: rname.clone(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
rname
|
|
||||||
}
|
|
||||||
pub fn new_enum(&mut self, name: String, state: State, desc: String) -> String {
|
|
||||||
let rname = generate_varname();
|
|
||||||
self.vars.insert(
|
|
||||||
name,
|
|
||||||
Variable {
|
|
||||||
vtype: VariableType::Enum,
|
|
||||||
desc,
|
|
||||||
state,
|
|
||||||
params: Variables {
|
|
||||||
vars: HashMap::new(),
|
|
||||||
},
|
|
||||||
rname: rname.clone(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
rname
|
|
||||||
}
|
|
||||||
|
|
||||||
// pub fn new_keyword(&mut self, name: String, state: State, desc: String) {
|
|
||||||
// self.vars.insert(
|
|
||||||
// name,
|
|
||||||
// Variable {
|
|
||||||
// vtype: VariableType::Keyword,
|
|
||||||
// desc,
|
|
||||||
// state,
|
|
||||||
// params: Variables {
|
|
||||||
// vars: HashMap::new(),
|
|
||||||
// },
|
|
||||||
// rname: generate_varname(),
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn new_func(&mut self, name: String, state: State, desc: String) -> String {
|
|
||||||
let rname = generate_varname();
|
|
||||||
self.vars.insert(
|
|
||||||
name,
|
|
||||||
Variable {
|
|
||||||
vtype: VariableType::Func,
|
|
||||||
desc,
|
|
||||||
state,
|
|
||||||
params: Variables {
|
|
||||||
vars: HashMap::new(),
|
|
||||||
},
|
|
||||||
rname: rname.clone(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
rname
|
|
||||||
}
|
|
||||||
pub fn get_var(&mut self, name: String, root: &mut Transpiler, state: State) -> String {
|
|
||||||
if let Some(x) = self.get_mut(name.clone()) {
|
|
||||||
return x.rname.clone();
|
|
||||||
} else {
|
|
||||||
root.problems.push(ProblemCap::Error(Problem {
|
|
||||||
problem_type: ProblemType::VariableNotFound,
|
|
||||||
problem_msg: format!("'{}' doesn't exist", &name),
|
|
||||||
state: state,
|
|
||||||
}));
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn iter_mut(
|
|
||||||
&mut self,
|
|
||||||
) -> std::collections::hash_map::IterMut<'_, std::string::String, Variable> {
|
|
||||||
self.vars.iter_mut()
|
|
||||||
}
|
|
||||||
pub fn get_mut(&mut self, name: String) -> Option<&mut Variable> {
|
|
||||||
if !name.contains("::") {
|
|
||||||
return self.vars.get_mut(&name);
|
|
||||||
}
|
|
||||||
if let Some((x, _)) = name.split_once("::") {
|
|
||||||
println!("{x}");
|
|
||||||
if let Some(v) = self.vars.get_mut(x) {
|
|
||||||
println!("{:?}", v);
|
|
||||||
let mut var = v;
|
|
||||||
for a in name.split("::") {
|
|
||||||
if let Some(b) = var.params.vars.get_mut(a) {
|
|
||||||
var = b;
|
|
||||||
} else {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Some(var);
|
|
||||||
}
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
pub fn expand(&mut self, vars: Variables) {
|
|
||||||
for (x, y) in vars.vars {
|
|
||||||
self.vars.insert(x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate_varname() -> String {
|
|
||||||
let mut rng = rand::thread_rng();
|
|
||||||
let charset: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
|
|
||||||
abcdefghijklmnopqrstuvwxyz\
|
|
||||||
0123456789";
|
|
||||||
let mut result = String::with_capacity(19);
|
|
||||||
result.push('_');
|
|
||||||
result.push('0');
|
|
||||||
result.push('x');
|
|
||||||
for _ in 0..14 {
|
|
||||||
let random_char = charset[rng.gen_range(0..charset.len())] as char;
|
|
||||||
result.push(random_char);
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|||||||
+19
-11
@@ -1,18 +1,20 @@
|
|||||||
WHITESPACE = _{ " " | "\t" | "\n" }
|
WHITESPACE = _{ " " | "\t" | "\n" }
|
||||||
|
|
||||||
|
// [chars]
|
||||||
|
comma = {","}
|
||||||
|
semicolon = {";"}
|
||||||
|
|
||||||
// [literals]
|
// [literals]
|
||||||
filepath = { ("/" | identifier | "-" | "." )+ }
|
filepath = { ("/"|('a'..'z' | 'a'..'z' | '0'..'9' | "_" | "-" | "."))+ }
|
||||||
include = { "#" ~ "include" ~ "\"" ~ filepath ~ "\"" }
|
include = { "#" ~ "include" ~ "\"" ~ filepath ~ "\"" }
|
||||||
include_global = { "#" ~ "include" ~ "<" ~ filepath ~ ">" }
|
include_global = { "#" ~ "include" ~ "<" ~ filepath ~ ">" }
|
||||||
round = { "(" ~ (expr)* ~ ")" }
|
round = { "(" ~ ((expr ~ comma)* ~ expr?) ~ ")" }
|
||||||
curly = { "{" ~ (code_expr)* ~ "}" }
|
curly = { "{" ~ (code_expr)* ~ "}" }
|
||||||
escape = { "\\" ~ ANY }
|
escape = { "\\" ~ ANY }
|
||||||
raw_string = { (!("\\" | "\"") ~ ANY)+ }
|
raw_string = { (!("\\" | "\"") ~ ANY)+ }
|
||||||
string = { "\"" ~ (raw_string | escape )* ~ "\"" }
|
string = { "\"" ~ (raw_string | escape )* ~ "\"" }
|
||||||
char = { "'" ~ (escape | ANY) ~ "'" }
|
char = { "'" ~ (escape | ANY) ~ "'" }
|
||||||
bool = @{"true" | "false"}
|
bool = @{"true" | "false"}
|
||||||
semicolon = {";"}
|
|
||||||
|
|
||||||
// [numbers]
|
// [numbers]
|
||||||
hex = @{ "0" ~ ("x"|"X") ~ ('0'..'9' | 'a'..'f' | 'A'..'F')*}
|
hex = @{ "0" ~ ("x"|"X") ~ ('0'..'9' | 'a'..'f' | 'A'..'F')*}
|
||||||
@@ -20,14 +22,18 @@ float = @{ ('0'..'9')* ~ "." ~ ('0'..'9')+ }
|
|||||||
int = @{ '0'..'9'+ }
|
int = @{ '0'..'9'+ }
|
||||||
|
|
||||||
// [identifiers]
|
// [identifiers]
|
||||||
identifier = @{ !(hex|float|int) ~ ("_" | 'a'..'z' | 'a'..'z') ~ ( "_" | 'a'..'z' | 'a'..'z' | int )* }
|
identifier = @{ !(hex|float|int) ~ ("." | "::" | "_" | 'a'..'z' | 'A'..'Z') ~ ( "." | "::" | "_" | 'a'..'z' | 'A'..'Z' | int )*}
|
||||||
|
def_identifier = {identifier ~ ("<" ~ ((def_identifier ~ comma)* ~ def_identifier?) ~ ">")?}
|
||||||
|
|
||||||
// [definitions]
|
// [definitions]
|
||||||
var_def = { identifier ~ identifier }
|
round_def = { "(" ~ ((var_def ~ comma)* ~ var_def?) ~ ")" }
|
||||||
var_def_set = { var_def ~ "=" ~ expr ~ semicolon }
|
var_def = { def_identifier ~ identifier }
|
||||||
func_def = { identifier ~ identifier ~ round ~ curly }
|
var_def_set = { var_def ~ "=" ~ expr }
|
||||||
|
var_set = { def_identifier ~ "=" ~ expr }
|
||||||
|
func_def = { def_identifier ~ identifier ~ round_def ~ curly }
|
||||||
|
|
||||||
expr = {
|
expr = {
|
||||||
|
(identifier ~ round) |
|
||||||
round |
|
round |
|
||||||
curly |
|
curly |
|
||||||
char |
|
char |
|
||||||
@@ -40,14 +46,16 @@ expr = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
code_expr = {
|
code_expr = {
|
||||||
var_def_set |
|
(var_def_set ~ semicolon) |
|
||||||
(var_def ~ semicolon)
|
(var_def ~ semicolon) |
|
||||||
|
(var_set ~ semicolon) |
|
||||||
|
(expr ~ semicolon)
|
||||||
}
|
}
|
||||||
|
|
||||||
top_expr = {
|
top_expr = {
|
||||||
(
|
(
|
||||||
func_def |
|
|
||||||
include |
|
include |
|
||||||
include_global
|
include_global |
|
||||||
|
func_def
|
||||||
)+
|
)+
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user