Browse Source

more code added, but with errors

pull/1/head
Jason Williams 6 years ago
parent
commit
99bdea009c
  1. 196
      src/lib/syntax/ast/punc.rs
  2. 112
      src/lib/syntax/lexer.rs

196
src/lib/syntax/ast/punc.rs

@ -3,103 +3,103 @@ use std::fmt::{Display, Error, Formatter};
/// Punctuation /// Punctuation
pub enum Punctuator { pub enum Punctuator {
/// `{` /// `{`
POpenBlock, OpenBlock,
/// `}` /// `}`
PCloseBlock, CloseBlock,
/// `(` /// `(`
POpenParen, OpenParen,
/// `)` /// `)`
PCloseParen, CloseParen,
/// `[` /// `[`
POpenBracket, OpenBracket,
/// `]` /// `]`
PCloseBracket, CloseBracket,
/// `.` /// `.`
PDot, Dot,
/// `;` /// `;`
PSemicolon, Semicolon,
/// `,` /// `,`
PComma, Comma,
/// `<` /// `<`
PLessThan, LessThan,
/// `>` /// `>`
PGreaterThan, GreaterThan,
/// `<=` /// `<=`
PLessThanOrEq, LessThanOrEq,
/// `>=` /// `>=`
PGreaterThanOrEq, GreaterThanOrEq,
/// `==` /// `==`
PEq, Eq,
/// `!=` /// `!=`
PNotEq, NotEq,
/// `===` /// `===`
PStrictEq, StrictEq,
/// `!==` /// `!==`
PStrictNotEq, StrictNotEq,
/// `+` /// `+`
PAdd, Add,
/// `-` /// `-`
PSub, Sub,
/// `*` /// `*`
PMul, Mul,
/// `/` /// `/`
PDiv, Div,
/// `%` /// `%`
PMod, Mod,
/// `++` /// `++`
PInc, Inc,
/// `--` /// `--`
PDec, Dec,
/// `<<` /// `<<`
PLeftSh, LeftSh,
/// `>>` /// `>>`
PRightSh, RightSh,
/// `>>>` /// `>>>`
PURightSh, URightSh,
/// `&` /// `&`
PAnd, And,
/// `|` /// `|`
POr, Or,
/// `^` /// `^`
PXor, Xor,
/// `!` /// `!`
PNot, Not,
/// `~` /// `~`
PNeg, Neg,
/// `&&` /// `&&`
PBoolAnd, BoolAnd,
/// `||` /// `||`
PBoolOr, BoolOr,
/// `?` /// `?`
PQuestion, Question,
/// `:` /// `:`
PColon, Colon,
/// `=` /// `=`
PAssign, Assign,
/// `+=` /// `+=`
PAssignAdd, AssignAdd,
/// `-=` /// `-=`
PAssignSub, AssignSub,
/// `*=` /// `*=`
PAssignMul, AssignMul,
/// `/=` /// `/=`
PAssignDiv, AssignDiv,
/// `%=` /// `%=`
PAssignMod, AssignMod,
/// `<<=` /// `<<=`
PAssignLeftSh, AssignLeftSh,
/// `>>=` /// `>>=`
PAssignRightSh, AssignRightSh,
/// `>>>=` /// `>>>=`
PAssignURightSh, AssignURightSh,
/// `&=` /// `&=`
PAssignAnd, AssignAnd,
/// `|=` /// `|=`
PAssignOr, AssignOr,
/// `^=` /// `^=`
PAssignXor, AssignXor,
/// `=>` /// `=>`
PArrow, Arrow,
} }
impl Display for Punctuator { impl Display for Punctuator {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
@ -107,55 +107,55 @@ impl Display for Punctuator {
f, f,
"{}", "{}",
match self { match self {
Punctuator::POpenBlock => "{", Punctuator::OpenBlock => "{",
Punctuator::PCloseBlock => "}", Punctuator::CloseBlock => "}",
Punctuator::POpenParen => "(", Punctuator::OpenParen => "(",
Punctuator::PCloseParen => ")", Punctuator::CloseParen => ")",
Punctuator::POpenBracket => "[", Punctuator::OpenBracket => "[",
Punctuator::PCloseBracket => "]", Punctuator::CloseBracket => "]",
Punctuator::PDot => ".", Punctuator::Dot => ".",
Punctuator::PSemicolon => ";", Punctuator::Semicolon => ";",
Punctuator::PComma => ",", Punctuator::Comma => ",",
Punctuator::PLessThan => "<", Punctuator::LessThan => "<",
Punctuator::PGreaterThan => ">", Punctuator::GreaterThan => ">",
Punctuator::PLessThanOrEq => "<=", Punctuator::LessThanOrEq => "<=",
Punctuator::PGreaterThanOrEq => ">=", Punctuator::GreaterThanOrEq => ">=",
Punctuator::PEq => "==", Punctuator::Eq => "==",
Punctuator::PNotEq => "!=", Punctuator::NotEq => "!=",
Punctuator::PStrictEq => "===", Punctuator::StrictEq => "===",
Punctuator::PStrictNotEq => "!==", Punctuator::StrictNotEq => "!==",
Punctuator::PAdd => "+", Punctuator::Add => "+",
Punctuator::PSub => "-", Punctuator::Sub => "-",
Punctuator::PMul => "*", Punctuator::Mul => "*",
Punctuator::PDiv => "/", Punctuator::Div => "/",
Punctuator::PMod => "%", Punctuator::Mod => "%",
Punctuator::PInc => "++", Punctuator::Inc => "++",
Punctuator::PDec => "--", Punctuator::Dec => "--",
Punctuator::PLeftSh => "<<", Punctuator::LeftSh => "<<",
Punctuator::PRightSh => ">>", Punctuator::RightSh => ">>",
Punctuator::PURightSh => ">>>", Punctuator::URightSh => ">>>",
Punctuator::PAnd => "&", Punctuator::And => "&",
Punctuator::POr => "|", Punctuator::Or => "|",
Punctuator::PXor => "^", Punctuator::Xor => "^",
Punctuator::PNot => "!", Punctuator::Not => "!",
Punctuator::PNeg => "~", Punctuator::Neg => "~",
Punctuator::PBoolAnd => "&&", Punctuator::BoolAnd => "&&",
Punctuator::PBoolOr => "||", Punctuator::BoolOr => "||",
Punctuator::PQuestion => "?", Punctuator::Question => "?",
Punctuator::PColon => ":", Punctuator::Colon => ":",
Punctuator::PAssign => "=", Punctuator::Assign => "=",
Punctuator::PAssignAdd => "+=", Punctuator::AssignAdd => "+=",
Punctuator::PAssignSub => "-=", Punctuator::AssignSub => "-=",
Punctuator::PAssignMul => "*=", Punctuator::AssignMul => "*=",
Punctuator::PAssignDiv => "/=", Punctuator::AssignDiv => "/=",
Punctuator::PAssignMod => "%=", Punctuator::AssignMod => "%=",
Punctuator::PAssignLeftSh => "<<=", Punctuator::AssignLeftSh => "<<=",
Punctuator::PAssignRightSh => ">>=", Punctuator::AssignRightSh => ">>=",
Punctuator::PAssignURightSh => ">>>=", Punctuator::AssignURightSh => ">>>=",
Punctuator::PAssignAnd => "&=", Punctuator::AssignAnd => "&=",
Punctuator::PAssignOr => "|=", Punctuator::AssignOr => "|=",
Punctuator::PAssignXor => "^=", Punctuator::AssignXor => "^=",
Punctuator::PArrow => "=>", Punctuator::Arrow => "=>",
} }
) )
} }

112
src/lib/syntax/lexer.rs

@ -1,9 +1,9 @@
use serialize::json::from_str;
use std::char::from_u32; use std::char::from_u32;
use std::error; use std::error;
use std::fmt; use std::fmt;
use std::iter::Peekable; use std::iter::Peekable;
use std::str::Chars; use std::str::Chars;
use std::str::FromStr;
use syntax::ast::punc::Punctuator; use syntax::ast::punc::Punctuator;
use syntax::ast::token::{Token, TokenData}; use syntax::ast::token::{Token, TokenData};
@ -75,6 +75,24 @@ impl<'a> Lexer<'a> {
self.buffer.next().ok_or(LexerError::new("next failed")) self.buffer.next().ok_or(LexerError::new("next failed"))
} }
/// Attempt to read until the end of the line and return the string
fn read_line(&mut self) -> Result<String, LexerError> {
let mut buf = String::new();
loop {
let ch = self.next()?;
match ch {
_ if ch.is_ascii_control() => {
break;
}
_ => {
buf.push(ch);
}
}
}
Ok(buf)
}
fn preview_next(&mut self) -> Result<&char, LexerError> { fn preview_next(&mut self) -> Result<&char, LexerError> {
// ok_or converts Option to a Result // ok_or converts Option to a Result
self.buffer self.buffer
@ -175,8 +193,7 @@ impl<'a> Lexer<'a> {
let ch = self.preview_next()?; let ch = self.preview_next()?;
match ch { match ch {
ch if ch.is_digit(16) => { ch if ch.is_digit(16) => {
self.next()?; buf.push(self.next()?);
buf.push(*ch);
} }
_ => break, _ => break,
} }
@ -199,14 +216,95 @@ impl<'a> Lexer<'a> {
_ => break, _ => break,
} }
} }
if gone_decimal { u64::from_str_radix(&buf, 8).unwrap()
from_str(&buf) };
self.push_token(TokenData::TNumericLiteral(num as f64))
}
_ if ch.is_digit(10) => {
let mut buf = ch.to_string();
loop {
let ch = self.preview_next()?;
match ch {
'.' => {
buf.push(self.next()?);
}
_ if ch.is_digit(10) => {
buf.push(self.next()?);
}
_ => break,
}
}
// TODO make this a bit more safe -------------------------------VVVV
self.push_token(TokenData::TNumericLiteral(f64::from_str(&buf).unwrap()))
}
_ if ch.is_alphabetic() || ch == '$' || ch == '_' => {
let mut buf = ch.to_string();
loop {
let ch = self.preview_next()?;
match ch {
_ if ch.is_alphabetic() || ch.is_digit(10) || *ch == '_' => {
buf.push(self.next()?);
}
_ => {
break;
}
}
}
// Match won't compare &String to &str so i need to convert it :(
let buf_compare: &str = &buf;
self.push_token(match buf_compare {
"true" => TokenData::TBooleanLiteral(true),
"false" => TokenData::TBooleanLiteral(false),
"null" => TokenData::TNullLiteral,
slice => match FromStr::from_str(slice) {
Ok(keyword) => TokenData::TKeyword(keyword),
Err(e) => TokenData::TIdentifier(buf.clone()),
},
});
}
';' => self.push_punc(Punctuator::Semicolon),
':' => self.push_punc(Punctuator::Colon),
'.' => self.push_punc(Punctuator::Dot),
'(' => self.push_punc(Punctuator::OpenParen),
')' => self.push_punc(Punctuator::CloseParen),
',' => self.push_punc(Punctuator::Comma),
'{' => self.push_punc(Punctuator::OpenBlock),
'}' => self.push_punc(Punctuator::CloseBlock),
'[' => self.push_punc(Punctuator::OpenBracket),
']' => self.push_punc(Punctuator::CloseBracket),
'?' => self.push_punc(Punctuator::Question),
'/' => {
let token = match self.preview_next()? {
// Matched comment
'/' => {
let comment = self.read_line()?;
TokenData::TComment(comment)
}
'*' => {
let mut buf = String::new();
loop {
match self.next()? {
'*' => {
if self.next_is('/')? {
break;
} else { } else {
u64::from_str_radix(&buf, 8) buf.push('*')
}
}
ch => buf.push(ch),
}
}
TokenData::TComment(buf)
} }
'=' => TokenData::TPunctuator(Punctuator::AssignDiv),
_ => TokenData::TPunctuator(Punctuator::Div),
}; };
self.push_token(TokenData::TNumericLiteral(num)) self.push_token(token)
} }
ch => panic!(
"{}:{}: Unexpected '{}'",
self.line_number, self.column_number, ch
),
} }
} }
} }

Loading…
Cancel
Save