-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Some potential work on typespecs and representation
Additionally some initial work on string escape processing.
- Loading branch information
Showing
13 changed files
with
285 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
|
||
|
||
import wright::box::Box; | ||
import wright::box::NullableBox; | ||
|
||
type Option<type T> { | ||
func some(t: T) -> Self; | ||
func none() -> Self; | ||
func is_some(&self) -> bool; | ||
func is_none(&self) -> bool; | ||
# ... etc | ||
} | ||
|
||
union DefaultOptionRepresentation<type T> { some: T | none: void }; | ||
|
||
implement Option<T> as DefaultOptionRepresentation<T> { | ||
const func some(t: T) -> Self { | ||
DefaultOptionRepresentation { some: t } | ||
} | ||
|
||
const func none() -> Self { | ||
DefaultOptionRepresentation { none: void } | ||
} | ||
|
||
const func is_some(&self) -> bool { | ||
self is DefaultOptionRepresentation.some | ||
} | ||
|
||
const func is_none(&self) -> bool { | ||
self is DefaultOptionRepresentation.none | ||
} | ||
|
||
# ... etc | ||
} | ||
|
||
implement Option<Box<T>> as NullableBox<T> { | ||
func some(t: T) -> Self { | ||
Box::new(t) as NullableBox | ||
} | ||
|
||
const func none() -> Self { | ||
NullableBox::null() | ||
} | ||
|
||
const fn is_some(&self) -> bool { | ||
!self.is_null() | ||
} | ||
|
||
const fn is_none(&self) -> bool { | ||
self.is_null() | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
|
||
For many languages, threading can be a point of tension. When to use it (especially now that single-threaded async is more common), | ||
how to use it, and how to optimize it are all common issues. | ||
|
||
In building wright, I decided it would be best to separate async and syncronous code/threads to avoid unnecessarily | ||
compiling/linking/running an async runtime to manage futures. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
//! Utilities for dealing with escaped characters in string and char literals. | ||
use std::{borrow::Cow, iter::Peekable, str::CharIndices}; | ||
|
||
pub fn unescape(source_str_lit_body: &str) -> Cow<'_, str> { | ||
Check warning on line 5 in wright/src/parser/ast/expression/literal/escapes.rs GitHub Actions / coverage
|
||
unimplemented!() | ||
} | ||
|
||
#[derive(Debug)] | ||
struct StringLiteralPartsIterator<'str_lit> { | ||
/// The body of the string literal being unescaped. | ||
str_lit_body: &'str_lit str, | ||
|
||
/// An iterator over the | ||
iter: Peekable<CharIndices<'str_lit>>, | ||
} | ||
|
||
enum StringLiteralPart<'str_lit> { | ||
/// A sequence of unescaped characters. | ||
UnescapedCharacters(&'str_lit str), | ||
|
||
UnicodeEscape { | ||
/// The part of the string literal that contains this escape sequence. | ||
matching_source: &'str_lit str, | ||
/// The result of attempting to parse the escaped value into a unicode codepoint. | ||
parsed: Option<char>, | ||
}, | ||
} | ||
|
||
enum UnicodeEscapeError { | ||
/// There were too many digits in the escape sequence. | ||
TooManyDigits, | ||
/// Empty escape sequence, | ||
Empty, | ||
/// The escaped digits do not represent a valid unicode codepoint. | ||
InvalidCodepoint, | ||
} | ||
|
||
impl<'str_lit> StringLiteralPartsIterator<'str_lit> { | ||
|
||
} | ||
|
||
impl<'str_lit> Iterator for StringLiteralPartsIterator<'str_lit> { | ||
type Item = StringLiteralPart<'str_lit>; | ||
|
||
fn next(&mut self) -> Option<Self::Item> { | ||
unimplemented!() | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
//! AST node representation and parsing implementation for string literals. | ||
use std::rc::Rc; | ||
|
||
use crate::parser::{ast::metadata::AstNodeMeta, state::ParserState, util::NodeParserResult, lexer::{tokens::{TokenTy, Token}, IndexedToken}, error::{ParserError, ParserErrorVariant}}; | ||
|
||
/// The value of a string literal in source code. | ||
#[derive(Debug, Clone)] | ||
pub enum StringLiteralValue<'src> { | ||
/// A string literal in source code without any escapes can be represented directly | ||
/// using a reference into the source code. This will refer to the string literal without the | ||
/// opening and closing quotatation marks. | ||
WithoutEscapes(&'src str), | ||
|
||
/// A string literal in source code with escapes must be represented using an owned string, as | ||
/// we have to do some processing to resolve all the escapes into the actual unescaped unicaode string. | ||
/// We store this in an [`Rc`] to make cloning less expensive, as we will not need to mutate this string | ||
/// while it's in the AST. | ||
WithEscapes(Rc<str>) | ||
} | ||
|
||
/// A string literal in source code. | ||
#[derive(Debug)] | ||
pub struct StringLit<'src> { | ||
/// The metadata about this node. | ||
pub meta: AstNodeMeta<'src>, | ||
/// A reference counted owned string representing the parsed value. | ||
pub value: StringLiteralValue<'src>, | ||
/// Format strings are denoted using '`' instead of '"'. Treat these similarly to string literals. | ||
pub is_format_string: bool, | ||
} | ||
|
||
impl<'src> StringLit<'src> { | ||
/// Parse a string literal from source code. If there is not a [`TokenTy::StringLit`] | ||
/// available from the parser state's lexer, then this will not mutate the parser state. | ||
pub fn parse(parser_state: &mut ParserState<'src>) -> NodeParserResult<Self> { | ||
// Peek the type of the next token or error out if there is not one. | ||
let peeked_token_ty = parser_state | ||
.peek_token_ty() | ||
// Dereferencing map here to prevent complaining about ref after mut borrow. | ||
.map(|token_ty: &TokenTy| *token_ty) | ||
// If there is not a next token, error out. | ||
.ok_or(ParserError { byte_range: parser_state.peek_byte_range(), ty: ParserErrorVariant::Expected("string literal") })?; | ||
|
||
// Mathc on the next token type available from the lexer. | ||
match peeked_token_ty { | ||
// Unterminated string literals produce an error. | ||
TokenTy::StringLit { is_terminated: false, .. } => Err(parser_state.peek_byte_range_into_error(ParserErrorVariant::UnterminatedStringLiteral)), | ||
|
||
// Terminated string literals produce a value. | ||
TokenTy::StringLit { is_format, .. } => { | ||
// Peek the important parts of the token. | ||
let IndexedToken { index, token: Token { length, .. } } = *parser_state.peek_token().unwrap(); | ||
// Get the associated part of source code, making an immutable reference into the parser state. | ||
let full_matching_source: &str = &parser_state.source[index..index+length]; | ||
// Get a reference to the body of the string literal itself (without the quotes or backticks for format | ||
// strings). | ||
let string_lit_body: &str = &full_matching_source[1..(full_matching_source.len()-1)]; | ||
|
||
|
||
|
||
unimplemented!() | ||
} | ||
|
||
// All other token types produce an error. | ||
_ => Err(parser_state.peek_byte_range_into_error(ParserErrorVariant::Expected("string literal"))), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.