[Compiler] Fix error in val/var error messages when the offending token is a string
This commit is contained in:
parent
d7bddfd549
commit
8a72b9308d
@ -25,7 +25,9 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> Option<SyntaxResult>
|
||||
}
|
||||
};
|
||||
|
||||
// var/val keyword
|
||||
/*
|
||||
* val/var keyword
|
||||
*/
|
||||
let (is_val, binding_token) = {
|
||||
let res1 = try_token_type(tokens, pos, TokenType::VAL);
|
||||
match res1 {
|
||||
@ -42,6 +44,9 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> Option<SyntaxResult>
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* identifier
|
||||
*/
|
||||
let identifier = match try_token_type(tokens, pos + 1, TokenType::Identifier) {
|
||||
Result3::Ok(t) => t,
|
||||
Result3::Err(t) => {
|
||||
@ -52,11 +57,10 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> Option<SyntaxResult>
|
||||
if is_val { "val" } else { "var" }
|
||||
),
|
||||
error_start: t.position,
|
||||
error_end: t.position + t.value.len(),
|
||||
error_end: t.get_end_position(),
|
||||
}));
|
||||
}
|
||||
Result3::None => {
|
||||
// TODO: Differentiate between no token found and incorrect token found.
|
||||
// The parser didn't find an Identifier after VAL/VAR
|
||||
return Some(SyntaxResult::Err(SyntaxError {
|
||||
reason: format!(
|
||||
@ -64,29 +68,30 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> Option<SyntaxResult>
|
||||
if is_val { "val" } else { "var" }
|
||||
),
|
||||
error_start: binding_token.position,
|
||||
error_end: binding_token.position + binding_token.value.len(),
|
||||
error_end: binding_token.get_end_position(),
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Equal (=) operator
|
||||
*/
|
||||
let _equal_operator: &Token = match try_operator(tokens, pos + 2, String::from("=")) {
|
||||
Result3::Ok(t) => t,
|
||||
Result3::Err(t) => {
|
||||
// TODO: Differentiate between no token found and incorrect token found.
|
||||
// The parser didn't find the `=` operator after the identifier
|
||||
// The parser found a token, but it's not the `=` operator
|
||||
return Some(SyntaxResult::Err(SyntaxError {
|
||||
reason: format!("There should be an equal sign `=` after the identifier",),
|
||||
error_start: identifier.position,
|
||||
error_end: identifier.position + identifier.value.len(),
|
||||
reason: format!("There should be an equal sign `=` after the identifier"),
|
||||
error_start: t.position,
|
||||
error_end: t.get_end_position(),
|
||||
}));
|
||||
}
|
||||
Result3::None => {
|
||||
// TODO: Differentiate between no token found and incorrect token found.
|
||||
// The parser didn't find the `=` operator after the identifier
|
||||
return Some(SyntaxResult::Err(SyntaxError {
|
||||
reason: format!("There should be an equal sign `=` after the identifier",),
|
||||
error_start: identifier.position,
|
||||
error_end: identifier.position + identifier.value.len(),
|
||||
error_end: identifier.get_end_position(),
|
||||
}));
|
||||
}
|
||||
};
|
||||
@ -128,6 +133,7 @@ fn try_token_type(tokens: &Vec<Token>, pos: usize, token_type: TokenType) -> Res
|
||||
fn try_operator(tokens: &Vec<Token>, pos: usize, operator: String) -> Result3<&Token> {
|
||||
match tokens.get(pos) {
|
||||
Some(t) if t.token_type == TokenType::Operator && t.value == operator => Result3::Ok(t),
|
||||
Some(t) if t.token_type == TokenType::Semicolon || t.token_type == TokenType::EOF => Result3::None,
|
||||
Some(t) => Result3::Err(t),
|
||||
None => Result3::None,
|
||||
}
|
||||
@ -233,7 +239,6 @@ mod tests {
|
||||
}
|
||||
|
||||
|
||||
// ERROR: when computing the length of the token "hello" the quotes are not considered
|
||||
let tokens = get_tokens(&String::from("val \"hello\"")).unwrap();
|
||||
let binding = try_parse(&tokens, 0).unwrap();
|
||||
|
||||
@ -245,4 +250,18 @@ mod tests {
|
||||
_ => panic!("Error expected")
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_return_error_when_equal_op_is_wrong() {
|
||||
let tokens = get_tokens(&String::from("val id \"error\"")).unwrap();
|
||||
let binding = try_parse(&tokens, 0).unwrap();
|
||||
|
||||
match binding {
|
||||
SyntaxResult::Err(error) => {
|
||||
assert_eq!(7, error.error_start);
|
||||
assert_eq!(14, error.error_end);
|
||||
}
|
||||
_ => panic!("Error expected")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,19 @@ pub struct Token {
|
||||
pub position: usize,
|
||||
}
|
||||
|
||||
impl Token {
|
||||
pub fn get_end_position(&self) -> usize {
|
||||
match self.token_type {
|
||||
TokenType::String => {
|
||||
self.position + self.value.len() + 2
|
||||
}
|
||||
_ => {
|
||||
self.position + self.value.len()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_eof(position: usize) -> Token {
|
||||
Token {
|
||||
token_type: TokenType::EOF,
|
||||
|
@ -12,53 +12,74 @@
|
||||
<!-- Google fonts - Inter -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100;300;400;500;700&display=swap" rel="stylesheet">
|
||||
|
||||
|
||||
<style>
|
||||
html {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
:root {
|
||||
--js-color: #FFE70B;
|
||||
--dark-color: #0f0f0f;
|
||||
}
|
||||
|
||||
body ::selection {
|
||||
#transition {
|
||||
width: 100%;
|
||||
height: 2vh;
|
||||
background-color: var(--js-color);
|
||||
color: var(--dark-color);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
body ::selection {
|
||||
color: var(--js-color);
|
||||
background-color: var(--dark-color);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="text-center">
|
||||
<div class="py-12 flex justify-center">
|
||||
<img src="/svg/logo_color.svg" alt="Misti logo" height="200" />
|
||||
</div>
|
||||
|
||||
<h2 class="text-xl px-2">
|
||||
<b>A type-safe, consistent, compiled language for JS</b>
|
||||
<body >
|
||||
<!--
|
||||
<div class="py-6 pt-12 flex justify-center">
|
||||
<img src="/svg/logo_color.svg" alt="Misti logo" height="200" />
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div id="greeter" style="background-color: black; color: var(--js-color); min-height: 100vh;">
|
||||
|
||||
<h2 class="text-6xl px-4 py-6 font-bold leading-snug">
|
||||
Typed.
|
||||
<br>
|
||||
Expressive.
|
||||
<br>
|
||||
Consistent.
|
||||
<br>
|
||||
Friendly.
|
||||
</h2>
|
||||
|
||||
<p class="p-4" style="color: #ffdf90;">
|
||||
Misti is <i>yet another</i> programming language that compiles to <b>JavaScript</b>.
|
||||
</p>
|
||||
|
||||
<!-- Demo code -->
|
||||
|
||||
<div class="px-4">
|
||||
<!-- TODO: add colors from variables -->
|
||||
<a class="inline-block py-1 px-4 my-1 mx-2 border-js-color bg-bg-color text-main-color hover:text-dark-color hover:bg-js-color border-2 rounded-full cursor-pointer select-none">
|
||||
Learn
|
||||
<div class="px-4 py-4">
|
||||
<a class="inline-block py-4 px-12 my-1 border-2 border-c5-primary
|
||||
bg-js-color
|
||||
text-dark-color
|
||||
rounded-xl cursor-pointer select-none font-medium shadow-md hover:shadow-2xl"
|
||||
href="/en/docs/latest/"
|
||||
>
|
||||
Get started
|
||||
</a>
|
||||
|
||||
<a class="inline-block py-1 px-4 my-1 mx-2 border-js-color bg-bg-color text-main-color hover:text-dark-color hover:bg-js-color border-2 rounded-full cursor-pointer select-none">
|
||||
<br>
|
||||
|
||||
<a class="inline-block py-4 px-12 my-1 border-2 border-c2-primary
|
||||
bg-c2-primary-container hover:bg-c2-primary
|
||||
text-c2-on-primary-container hover:text-c2-on-primary
|
||||
rounded-xl cursor-pointer select-none transition-colors"
|
||||
href="/en/api/latest/"
|
||||
>
|
||||
API
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="transition"></div>
|
||||
|
||||
<script>
|
||||
// Inter - Google fonts - load here as to not interrupt the page
|
||||
const linkEl = document.createElement("link");
|
||||
linkEl.href = "https://fonts.googleapis.com/css2?family=Inter:wght@100;300;400;500;700&display=swap";
|
||||
linkEl.rel = "stylesheet";
|
||||
|
||||
document.head.appendChild(linkEl);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -29,6 +29,9 @@ body ::selection {
|
||||
|
||||
/* C2 Material Colors */
|
||||
--c2-primary: #90ccff;
|
||||
--c2-on-primary: #003351;
|
||||
--c2-primary-container: #004b72;
|
||||
--c2-on-primary-container: #cce5ff;
|
||||
|
||||
/* C3 Material Colors */
|
||||
--c3-primary: #ffaed7;
|
||||
@ -64,6 +67,9 @@ body ::selection {
|
||||
|
||||
/* C2 Material Colors */
|
||||
--c2-primary: #006397;
|
||||
--c2-on-primary: #ffffff;
|
||||
--c2-primary-container: #cce5ff;
|
||||
--c2-on-primary-container: #001e31;
|
||||
|
||||
/* C3 Material Colors */
|
||||
--c3-primary: #954170;
|
||||
|
@ -5,6 +5,7 @@ module.exports = {
|
||||
colors: {
|
||||
transparent: 'transparent',
|
||||
current: 'currentColor',
|
||||
white: "#ffffff",
|
||||
|
||||
"js-color": "var(--js-color)",
|
||||
"dark-color": "var(--dark-color)",
|
||||
@ -22,8 +23,14 @@ module.exports = {
|
||||
"code-bg-color": "var(--code-bg-color)",
|
||||
"code-color": "var(--code-color)",
|
||||
"border-color": "var(--border-color)",
|
||||
|
||||
"c1-primary": "var(--c1-primary)",
|
||||
|
||||
"c2-primary": "var(--c2-primary)",
|
||||
"c2-on-primary": "var(--c2-on-primary)",
|
||||
"c2-primary-container": "var(--c2-primary-container)",
|
||||
"c2-on-primary-container": "var(--c2-on-primary-container)",
|
||||
|
||||
"c3-primary": "var(--c3-primary)",
|
||||
"c3-on-primary": "var(--c3-on-primary)",
|
||||
"c3-primary-container": "var(--c3-primary-container)",
|
||||
@ -35,6 +42,9 @@ module.exports = {
|
||||
"c5-on-primary-container": "var(--c5-on-primary-container)",
|
||||
"bg-color": "var(--bg-color)",
|
||||
},
|
||||
borderWidth: {
|
||||
'1': '1px'
|
||||
},
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
|
Loading…
Reference in New Issue
Block a user