Started writing new expression parser (It does not work right now)
This commit is contained in:
parent
3753f6d8f5
commit
8f98528a15
106
src/ast.rs
106
src/ast.rs
|
@ -6,8 +6,8 @@ use std::collections::HashMap;
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Function {
|
pub struct Function {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub statements: Vec<Statement>,
|
pub statement: Statement,
|
||||||
pub n_args: u64,
|
pub args: Vec<String>,
|
||||||
assembly: Option<String>,
|
assembly: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,27 @@ pub enum Statement {
|
||||||
Scope(Vec<Statement>),
|
Scope(Vec<Statement>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum Expression {
|
||||||
|
Literal(Literal),
|
||||||
|
Variable(String),
|
||||||
|
Unary(Unary, Box<Expression>),
|
||||||
|
Grouping(Box<Expression>),
|
||||||
|
Binary(BinOp, Box<Expression>, Box<Expression>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum Unary {
|
||||||
|
PointerTo,
|
||||||
|
ValueFrom,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum BinOp {
|
||||||
|
Plus,
|
||||||
|
Minus,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ValueNode {
|
pub enum ValueNode {
|
||||||
Literal(Literal),
|
Literal(Literal),
|
||||||
|
@ -48,11 +69,11 @@ pub trait Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Function {
|
impl Function {
|
||||||
pub fn new(name: String, n_args: u64, statements: Vec<Statement>) -> Function {
|
pub fn new(name: String, args: Vec<String>, statement: Statement) -> Function {
|
||||||
Function {
|
Function {
|
||||||
name,
|
name,
|
||||||
statements,
|
statement,
|
||||||
n_args,
|
args,
|
||||||
assembly: None,
|
assembly: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,8 +99,8 @@ fn get_default_functions() -> HashMap<String, Function> {
|
||||||
"out".to_string(),
|
"out".to_string(),
|
||||||
Function {
|
Function {
|
||||||
name: "out".to_string(),
|
name: "out".to_string(),
|
||||||
statements: vec![],
|
statement: Statement::FunctionCall("".to_string(), vec![]),
|
||||||
n_args: 1,
|
args: vec!["value".to_string()],
|
||||||
assembly: Some(
|
assembly: Some(
|
||||||
"
|
"
|
||||||
out:
|
out:
|
||||||
|
@ -118,8 +139,8 @@ F-OUT JMP 0xFF"
|
||||||
"exit".to_string(),
|
"exit".to_string(),
|
||||||
Function {
|
Function {
|
||||||
name: "exit".to_string(),
|
name: "exit".to_string(),
|
||||||
statements: vec![],
|
statement: Statement::FunctionCall("".to_string(), vec![]),
|
||||||
n_args: 0,
|
args: vec![],
|
||||||
assembly: Some(
|
assembly: Some(
|
||||||
"
|
"
|
||||||
exit:
|
exit:
|
||||||
|
@ -136,9 +157,25 @@ impl Node for Function {
|
||||||
fn to_assembly(&self, state: &mut AssemblerState) -> String {
|
fn to_assembly(&self, state: &mut AssemblerState) -> String {
|
||||||
match &self.assembly {
|
match &self.assembly {
|
||||||
Some(v) => v.to_string(),
|
Some(v) => v.to_string(),
|
||||||
None => format!(
|
None => {
|
||||||
"{}:
|
let name = &self.name;
|
||||||
{}
|
|
||||||
|
let mut pop_argument_assembly = "ROM-OUT FLAGS-IN 0x80".to_string();
|
||||||
|
|
||||||
|
for argument in &self.args {
|
||||||
|
state.variables.push(argument.to_string());
|
||||||
|
pop_argument_assembly += "
|
||||||
|
SE-OUT A-IN 0xFF
|
||||||
|
ROM-OUT B-IN 0x01
|
||||||
|
ALU-OUT SE-IN 0xFF
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
let statement_assembly = self.statement.to_assembly(state);
|
||||||
|
format!(
|
||||||
|
"{name}:
|
||||||
|
{statement_assembly}
|
||||||
|
{pop_argument_assembly}
|
||||||
;
|
;
|
||||||
; Pop the return address of the stack
|
; Pop the return address of the stack
|
||||||
;
|
;
|
||||||
|
@ -154,15 +191,8 @@ ROM-OUT FLAGS-IN 0x00 ; Add mode
|
||||||
|
|
||||||
F-OUT JMP 0xFF
|
F-OUT JMP 0xFF
|
||||||
",
|
",
|
||||||
self.name,
|
)
|
||||||
{
|
}
|
||||||
self.statements
|
|
||||||
.iter()
|
|
||||||
.map(|x| x.to_assembly(state))
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join("\n")
|
|
||||||
}
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,15 +201,7 @@ impl Node for Statement {
|
||||||
fn to_assembly(&self, state: &mut AssemblerState) -> String {
|
fn to_assembly(&self, state: &mut AssemblerState) -> String {
|
||||||
match self {
|
match self {
|
||||||
Statement::Scope(statements) => {
|
Statement::Scope(statements) => {
|
||||||
let init_assembly = "
|
let dropped_length = state.variables.len();
|
||||||
ROM-OUT FLAGS-IN 0x00
|
|
||||||
SE-OUT A-IN 0xFF
|
|
||||||
ROM-OUT B-IN 0x01
|
|
||||||
ALU-OUT SE-IN 0xFF
|
|
||||||
"
|
|
||||||
.to_string();
|
|
||||||
|
|
||||||
state.variables.push("start scope".to_string());
|
|
||||||
|
|
||||||
let statement_assembly = statements
|
let statement_assembly = statements
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -187,33 +209,20 @@ ALU-OUT SE-IN 0xFF
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join("\n");
|
.join("\n");
|
||||||
|
|
||||||
let mut stop_assembly = "".to_string();
|
while state.variables.len() > dropped_length {
|
||||||
|
|
||||||
while state.variables.contains(&"start scope".to_string()) {
|
|
||||||
stop_assembly += &format!(
|
|
||||||
"
|
|
||||||
ROM-OUT FLAGS-IN 0x80
|
|
||||||
SE-OUT A-IN 0xFF
|
|
||||||
ROM-OUT B-IN 0x01
|
|
||||||
ALU-OUT SE-IN 0xFF
|
|
||||||
ROM-OUT FLAGS-IN 0x00"
|
|
||||||
);
|
|
||||||
state.variables.pop();
|
state.variables.pop();
|
||||||
}
|
}
|
||||||
|
dbg!(&state.variables);
|
||||||
|
|
||||||
format!(
|
statement_assembly
|
||||||
"{init_assembly}
|
|
||||||
{statement_assembly}
|
|
||||||
{stop_assembly}"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Statement::FunctionCall(name, arguments) => {
|
Statement::FunctionCall(name, arguments) => {
|
||||||
if !state.functions.contains_key(name) {
|
if !state.functions.contains_key(name) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
state.variables.push(name.to_owned());
|
state.variables.push(name.to_owned());
|
||||||
|
dbg!(&state.variables);
|
||||||
let argument_assembly: String = arguments
|
let argument_assembly: String = arguments
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|x| x.to_assembly(state))
|
.map(|x| x.to_assembly(state))
|
||||||
|
@ -226,7 +235,7 @@ ROM-OUT FLAGS-IN 0x00"
|
||||||
.map(char::from)
|
.map(char::from)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for _ in 0..state.functions.get(name).unwrap().n_args {
|
for _ in &state.functions.get(name).unwrap().args {
|
||||||
state.variables.pop();
|
state.variables.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,6 +325,7 @@ impl Node for ValueNode {
|
||||||
- state.variables.iter().position(|x| x == name).unwrap()
|
- state.variables.iter().position(|x| x == name).unwrap()
|
||||||
- 1;
|
- 1;
|
||||||
|
|
||||||
|
dbg!(&state.variables);
|
||||||
state.variables.push(name.to_owned());
|
state.variables.push(name.to_owned());
|
||||||
|
|
||||||
format!(
|
format!(
|
||||||
|
|
23
src/main.rs
23
src/main.rs
|
@ -1,17 +1,28 @@
|
||||||
|
use crate::tokeniser::Token;
|
||||||
|
|
||||||
mod ast;
|
mod ast;
|
||||||
mod parse;
|
mod parse;
|
||||||
mod tokeniser;
|
mod tokeniser;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let filename = "test.plonkus";
|
// let filename: &str = &std::env::args().collect::<Vec<String>>()[1];
|
||||||
|
|
||||||
let contents = std::fs::read_to_string(filename).expect(&format!("No file named {}", filename));
|
// let contents = std::fs::read_to_string(filename).expect(&format!("No file named {}", filename));
|
||||||
|
|
||||||
let tokens = tokeniser::tokenise(contents);
|
// let tokens = tokeniser::tokenise(contents);
|
||||||
|
|
||||||
let functions = dbg!(parse::ast(tokens));
|
// let functions = dbg!(parse::ast(tokens));
|
||||||
|
|
||||||
let assembly = ast::to_assembly(functions);
|
// let assembly = ast::to_assembly(functions);
|
||||||
|
|
||||||
println!("{}", assembly);
|
// println!("{}", assembly);
|
||||||
|
|
||||||
|
let mut i: usize = 0;
|
||||||
|
let tokens: Vec<tokeniser::Token> = vec![
|
||||||
|
Token::OpenParanthesis,
|
||||||
|
Token::Star,
|
||||||
|
Token::Number("2".to_string()),
|
||||||
|
Token::CloseParanthesis,
|
||||||
|
];
|
||||||
|
dbg!(parse::parse_expression(&tokens, &mut i));
|
||||||
}
|
}
|
||||||
|
|
175
src/parse.rs
175
src/parse.rs
|
@ -66,77 +66,143 @@ fn parse_math(tokens: &Vec<Token>) -> ValueNode {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_statements(tokens: &Vec<Token>, starting_i: usize) -> (Vec<Statement>, usize) {
|
fn parse_basic(tokens: &Vec<Token>, i: &mut usize) -> Expression {
|
||||||
let mut i = starting_i;
|
let literal = match &tokens[*i] {
|
||||||
|
Token::Identifier(identifier) => Expression::Variable(identifier.to_owned()),
|
||||||
|
Token::Number(number) => Expression::Literal(Literal::Int(number.parse::<i64>().unwrap())),
|
||||||
|
_ => todo!(),
|
||||||
|
};
|
||||||
|
*i += 1;
|
||||||
|
literal
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_grouping(tokens: &Vec<Token>, i: &mut usize) -> Expression {
|
||||||
|
match &tokens[*i] {
|
||||||
|
Token::OpenParanthesis => {
|
||||||
|
*i += 1;
|
||||||
|
}
|
||||||
|
_ => todo!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let inner_expression = parse_expression(tokens, i);
|
||||||
|
|
||||||
|
match &tokens[*i] {
|
||||||
|
Token::CloseParanthesis => {}
|
||||||
|
_ => todo!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
inner_expression
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: replace parse_math with this recursive function
|
||||||
|
pub fn parse_expression(tokens: &Vec<Token>, i: &mut usize) -> Expression {
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum OpExpr {
|
||||||
|
Expression(Expression),
|
||||||
|
BinOp(BinOp),
|
||||||
|
Unary(Unary),
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut in_expressions_and_operators: Vec<OpExpr> = Vec::new();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
in_expressions_and_operators.push(match &tokens[*i] {
|
||||||
|
Token::OpenParanthesis => OpExpr::Expression(parse_grouping(tokens, i)),
|
||||||
|
Token::Plus => {
|
||||||
|
*i += 1;
|
||||||
|
OpExpr::BinOp(BinOp::Plus)
|
||||||
|
}
|
||||||
|
Token::Minus => {
|
||||||
|
*i += 1;
|
||||||
|
OpExpr::BinOp(BinOp::Minus)
|
||||||
|
}
|
||||||
|
Token::Ampersand => {
|
||||||
|
*i += 1;
|
||||||
|
OpExpr::Unary(Unary::ValueFrom)
|
||||||
|
}
|
||||||
|
Token::Star => {
|
||||||
|
*i += 1;
|
||||||
|
OpExpr::Unary(Unary::PointerTo)
|
||||||
|
}
|
||||||
|
Token::Number(_) => OpExpr::Expression(parse_basic(tokens, i)),
|
||||||
|
_other => break,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
dbg!(in_expressions_and_operators);
|
||||||
|
Expression::Variable("a".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_statements(tokens: &Vec<Token>, i: &mut usize) -> Vec<Statement> {
|
||||||
|
dbg!(&i);
|
||||||
let mut statements = Vec::new();
|
let mut statements = Vec::new();
|
||||||
while i < tokens.len() {
|
while *i < tokens.len() {
|
||||||
statements.push(match &tokens[i] {
|
statements.push(match &tokens[*i] {
|
||||||
Token::OpenSquiglyBracket => {
|
Token::OpenSquiglyBracket => {
|
||||||
let (statements, added_to_i) = parse_statements(tokens, i + 1);
|
*i += 1;
|
||||||
i = added_to_i + 1;
|
let statements = parse_statements(tokens, i);
|
||||||
Statement::Scope(statements)
|
Statement::Scope(statements)
|
||||||
}
|
}
|
||||||
Token::Keyword(Keyword::Let) => {
|
Token::Keyword(Keyword::Let) => {
|
||||||
i += 1;
|
*i += 1;
|
||||||
let name = match tokens[i].clone() {
|
let name = match tokens[*i].clone() {
|
||||||
Token::Identifier(identifier) => identifier,
|
Token::Identifier(identifier) => identifier,
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
i += 1;
|
*i += 1;
|
||||||
match tokens[i].clone() {
|
match tokens[*i].clone() {
|
||||||
Token::Equals => {}
|
Token::Equals => {}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
i += 1;
|
*i += 1;
|
||||||
|
|
||||||
let mut declaration_tokens: Vec<Token> = Vec::new();
|
let mut declaration_tokens: Vec<Token> = Vec::new();
|
||||||
while tokens[i] != Token::Semi {
|
while tokens[*i] != Token::Semi {
|
||||||
declaration_tokens.push(tokens[i].clone());
|
declaration_tokens.push(tokens[*i].clone());
|
||||||
i += 1;
|
*i += 1;
|
||||||
}
|
}
|
||||||
Statement::VariableDeclaration(name, parse_math(&declaration_tokens))
|
Statement::VariableDeclaration(name, parse_math(&declaration_tokens))
|
||||||
}
|
}
|
||||||
Token::Keyword(Keyword::Assign) => {
|
Token::Keyword(Keyword::Assign) => {
|
||||||
i += 1;
|
*i += 1;
|
||||||
let name = match tokens[i].clone() {
|
let name = match tokens[*i].clone() {
|
||||||
Token::Identifier(identifier) => identifier,
|
Token::Identifier(identifier) => identifier,
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
i += 1;
|
*i += 1;
|
||||||
match tokens[i].clone() {
|
match tokens[*i].clone() {
|
||||||
Token::Equals => {}
|
Token::Equals => {}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
i += 1;
|
*i += 1;
|
||||||
|
|
||||||
let mut declaration_tokens: Vec<Token> = Vec::new();
|
let mut declaration_tokens: Vec<Token> = Vec::new();
|
||||||
while tokens[i] != Token::Semi {
|
while tokens[*i] != Token::Semi {
|
||||||
declaration_tokens.push(tokens[i].clone());
|
declaration_tokens.push(tokens[*i].clone());
|
||||||
i += 1;
|
*i += 1;
|
||||||
}
|
}
|
||||||
Statement::VariableAssignment(name, parse_math(&declaration_tokens))
|
Statement::VariableAssignment(name, parse_math(&declaration_tokens))
|
||||||
}
|
}
|
||||||
Token::Identifier(identifier) => {
|
Token::Identifier(identifier) => {
|
||||||
i += 1;
|
*i += 1;
|
||||||
|
|
||||||
let mut declaration_tokens: Vec<Vec<Token>> = Vec::new();
|
let mut declaration_tokens: Vec<Vec<Token>> = Vec::new();
|
||||||
|
|
||||||
i += 1;
|
*i += 1;
|
||||||
while tokens[i] != Token::CloseParanthesis {
|
while tokens[*i] != Token::CloseParanthesis {
|
||||||
let mut argument_tokens: Vec<Token> = Vec::new();
|
let mut argument_tokens: Vec<Token> = Vec::new();
|
||||||
while tokens[i] != Token::Comma {
|
while tokens[*i] != Token::Comma {
|
||||||
argument_tokens.push(tokens[i].clone());
|
argument_tokens.push(tokens[*i].clone());
|
||||||
i += 1;
|
*i += 1;
|
||||||
}
|
}
|
||||||
declaration_tokens.push(argument_tokens);
|
declaration_tokens.push(argument_tokens);
|
||||||
i += 1;
|
*i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
i += 1;
|
*i += 1;
|
||||||
|
|
||||||
let mut arguments: Vec<ValueNode> = Vec::new();
|
let mut arguments: Vec<ValueNode> = Vec::new();
|
||||||
|
|
||||||
|
@ -150,19 +216,35 @@ fn parse_statements(tokens: &Vec<Token>, starting_i: usize) -> (Vec<Statement>,
|
||||||
Statement::FunctionCall(identifier.to_owned(), arguments)
|
Statement::FunctionCall(identifier.to_owned(), arguments)
|
||||||
}
|
}
|
||||||
Token::CloseSquiglyBracket => {
|
Token::CloseSquiglyBracket => {
|
||||||
return (statements, i);
|
*i += 1;
|
||||||
|
return statements;
|
||||||
}
|
}
|
||||||
Token::Semi => {
|
Token::Semi => {
|
||||||
i += 1;
|
*i += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
_other => {
|
_other => {
|
||||||
dbg!(_other);
|
dbg!(_other);
|
||||||
|
dbg!(i);
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
(statements, i)
|
*i += 1;
|
||||||
|
statements
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_arguments(tokens: &Vec<Token>, i: &mut usize) -> Vec<String> {
|
||||||
|
let mut argument_variables = Vec::new();
|
||||||
|
while tokens[*i] != Token::OpenSquiglyBracket {
|
||||||
|
match &tokens[*i] {
|
||||||
|
Token::Identifier(identifier) => argument_variables.push(identifier.to_owned()),
|
||||||
|
Token::OpenSquiglyBracket => {}
|
||||||
|
_other => todo!(),
|
||||||
|
}
|
||||||
|
*i += 1;
|
||||||
|
}
|
||||||
|
argument_variables
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ast(tokens: Vec<Token>) -> Vec<Function> {
|
pub fn ast(tokens: Vec<Token>) -> Vec<Function> {
|
||||||
|
@ -172,18 +254,23 @@ pub fn ast(tokens: Vec<Token>) -> Vec<Function> {
|
||||||
while i < tokens.len() {
|
while i < tokens.len() {
|
||||||
match &tokens[i] {
|
match &tokens[i] {
|
||||||
Token::Keyword(Keyword::Function) => {
|
Token::Keyword(Keyword::Function) => {
|
||||||
let (statements, added_to_i) = parse_statements(&tokens, i + 4);
|
i += 1;
|
||||||
let statements = vec![Statement::Scope(statements)];
|
|
||||||
let function_name = match &tokens[i + 1] {
|
let name = match &tokens[i] {
|
||||||
Token::Identifier(identifier) => identifier.to_owned(),
|
Token::Identifier(identifier) => identifier,
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
};
|
}
|
||||||
let n_args = match &tokens[i + 2] {
|
.to_owned();
|
||||||
Token::Number(num) => num.parse::<u64>().unwrap(),
|
i += 1;
|
||||||
_ => todo!(),
|
|
||||||
};
|
let arguments = parse_arguments(&tokens, &mut i);
|
||||||
i += added_to_i;
|
|
||||||
functions.push(Function::new(function_name, n_args, statements));
|
i += 1;
|
||||||
|
let statements = parse_statements(&tokens, &mut i);
|
||||||
|
|
||||||
|
let statement = Statement::Scope(statements);
|
||||||
|
|
||||||
|
functions.push(Function::new(name, arguments, statement));
|
||||||
}
|
}
|
||||||
_other => {
|
_other => {
|
||||||
dbg!(&functions);
|
dbg!(&functions);
|
||||||
|
|
|
@ -5,6 +5,8 @@ pub enum Token {
|
||||||
Comma,
|
Comma,
|
||||||
Plus,
|
Plus,
|
||||||
Minus,
|
Minus,
|
||||||
|
Ampersand,
|
||||||
|
Star,
|
||||||
Number(String),
|
Number(String),
|
||||||
Identifier(String),
|
Identifier(String),
|
||||||
Keyword(Keyword),
|
Keyword(Keyword),
|
||||||
|
@ -85,22 +87,24 @@ fn tokenise_current_character(
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
use std::option::Option::Some as s;
|
use Option::Some as s;
|
||||||
use Token as T;
|
use Token as T;
|
||||||
use TokenFinishedUnfinished::Unfinished as uf;
|
use TokenFinishedUnfinished::Unfinished as uf;
|
||||||
|
|
||||||
match current_character {
|
uf(match current_character {
|
||||||
';' => uf(s(T::Semi)),
|
';' => s(T::Semi),
|
||||||
'(' => uf(s(T::OpenParanthesis)),
|
'(' => s(T::OpenParanthesis),
|
||||||
')' => uf(s(T::CloseParanthesis)),
|
')' => s(T::CloseParanthesis),
|
||||||
'{' => uf(s(T::OpenSquiglyBracket)),
|
'{' => s(T::OpenSquiglyBracket),
|
||||||
'}' => uf(s(T::CloseSquiglyBracket)),
|
'}' => s(T::CloseSquiglyBracket),
|
||||||
'=' => uf(s(T::Equals)),
|
'=' => s(T::Equals),
|
||||||
',' => uf(s(T::Comma)),
|
',' => s(T::Comma),
|
||||||
'+' => uf(s(T::Plus)),
|
'+' => s(T::Plus),
|
||||||
'-' => uf(s(T::Minus)),
|
'-' => s(T::Minus),
|
||||||
_ => uf(None),
|
'&' => s(T::Ampersand),
|
||||||
}
|
'*' => s(T::Star),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(v) => Finished(v),
|
Some(v) => Finished(v),
|
||||||
|
|
Loading…
Reference in a new issue