[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 (is_val, binding_token) = {
|
||||||
let res1 = try_token_type(tokens, pos, TokenType::VAL);
|
let res1 = try_token_type(tokens, pos, TokenType::VAL);
|
||||||
match res1 {
|
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) {
|
let identifier = match try_token_type(tokens, pos + 1, TokenType::Identifier) {
|
||||||
Result3::Ok(t) => t,
|
Result3::Ok(t) => t,
|
||||||
Result3::Err(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" }
|
if is_val { "val" } else { "var" }
|
||||||
),
|
),
|
||||||
error_start: t.position,
|
error_start: t.position,
|
||||||
error_end: t.position + t.value.len(),
|
error_end: t.get_end_position(),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
Result3::None => {
|
Result3::None => {
|
||||||
// TODO: Differentiate between no token found and incorrect token found.
|
|
||||||
// The parser didn't find an Identifier after VAL/VAR
|
// The parser didn't find an Identifier after VAL/VAR
|
||||||
return Some(SyntaxResult::Err(SyntaxError {
|
return Some(SyntaxResult::Err(SyntaxError {
|
||||||
reason: format!(
|
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" }
|
if is_val { "val" } else { "var" }
|
||||||
),
|
),
|
||||||
error_start: binding_token.position,
|
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("=")) {
|
let _equal_operator: &Token = match try_operator(tokens, pos + 2, String::from("=")) {
|
||||||
Result3::Ok(t) => t,
|
Result3::Ok(t) => t,
|
||||||
Result3::Err(t) => {
|
Result3::Err(t) => {
|
||||||
// TODO: Differentiate between no token found and incorrect token found.
|
// The parser found a token, but it's not the `=` operator
|
||||||
// The parser didn't find the `=` operator after the identifier
|
|
||||||
return Some(SyntaxResult::Err(SyntaxError {
|
return Some(SyntaxResult::Err(SyntaxError {
|
||||||
reason: format!("There should be an equal sign `=` after the identifier",),
|
reason: format!("There should be an equal sign `=` after the identifier"),
|
||||||
error_start: identifier.position,
|
error_start: t.position,
|
||||||
error_end: identifier.position + identifier.value.len(),
|
error_end: t.get_end_position(),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
Result3::None => {
|
Result3::None => {
|
||||||
// TODO: Differentiate between no token found and incorrect token found.
|
|
||||||
// The parser didn't find the `=` operator after the identifier
|
// The parser didn't find the `=` operator after the identifier
|
||||||
return Some(SyntaxResult::Err(SyntaxError {
|
return Some(SyntaxResult::Err(SyntaxError {
|
||||||
reason: format!("There should be an equal sign `=` after the identifier",),
|
reason: format!("There should be an equal sign `=` after the identifier",),
|
||||||
error_start: identifier.position,
|
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> {
|
fn try_operator(tokens: &Vec<Token>, pos: usize, operator: String) -> Result3<&Token> {
|
||||||
match tokens.get(pos) {
|
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::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),
|
Some(t) => Result3::Err(t),
|
||||||
None => Result3::None,
|
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 tokens = get_tokens(&String::from("val \"hello\"")).unwrap();
|
||||||
let binding = try_parse(&tokens, 0).unwrap();
|
let binding = try_parse(&tokens, 0).unwrap();
|
||||||
|
|
||||||
@ -245,4 +250,18 @@ mod tests {
|
|||||||
_ => panic!("Error expected")
|
_ => 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,
|
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 {
|
pub fn new_eof(position: usize) -> Token {
|
||||||
Token {
|
Token {
|
||||||
token_type: TokenType::EOF,
|
token_type: TokenType::EOF,
|
||||||
|
@ -12,53 +12,74 @@
|
|||||||
<!-- Google fonts - Inter -->
|
<!-- Google fonts - Inter -->
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<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>
|
<style>
|
||||||
html {
|
#transition {
|
||||||
font-size: 20px;
|
width: 100%;
|
||||||
}
|
height: 2vh;
|
||||||
|
|
||||||
:root {
|
|
||||||
--js-color: #FFE70B;
|
|
||||||
--dark-color: #0f0f0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
body ::selection {
|
|
||||||
background-color: var(--js-color);
|
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>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body >
|
||||||
<div class="text-center">
|
<!--
|
||||||
<div class="py-12 flex justify-center">
|
<div class="py-6 pt-12 flex justify-center">
|
||||||
<img src="/svg/logo_color.svg" alt="Misti logo" height="200" />
|
<img src="/svg/logo_color.svg" alt="Misti logo" height="200" />
|
||||||
</div>
|
</div>
|
||||||
|
-->
|
||||||
<h2 class="text-xl px-2">
|
|
||||||
<b>A type-safe, consistent, compiled language for JS</b>
|
<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>
|
</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 -->
|
<!-- Demo code -->
|
||||||
|
|
||||||
<div class="px-4">
|
<div class="px-4 py-4">
|
||||||
<!-- TODO: add colors from variables -->
|
<a class="inline-block py-4 px-12 my-1 border-2 border-c5-primary
|
||||||
<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">
|
bg-js-color
|
||||||
Learn
|
text-dark-color
|
||||||
|
rounded-xl cursor-pointer select-none font-medium shadow-md hover:shadow-2xl"
|
||||||
|
href="/en/docs/latest/"
|
||||||
|
>
|
||||||
|
Get started
|
||||||
</a>
|
</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
|
API
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -29,6 +29,9 @@ body ::selection {
|
|||||||
|
|
||||||
/* C2 Material Colors */
|
/* C2 Material Colors */
|
||||||
--c2-primary: #90ccff;
|
--c2-primary: #90ccff;
|
||||||
|
--c2-on-primary: #003351;
|
||||||
|
--c2-primary-container: #004b72;
|
||||||
|
--c2-on-primary-container: #cce5ff;
|
||||||
|
|
||||||
/* C3 Material Colors */
|
/* C3 Material Colors */
|
||||||
--c3-primary: #ffaed7;
|
--c3-primary: #ffaed7;
|
||||||
@ -64,6 +67,9 @@ body ::selection {
|
|||||||
|
|
||||||
/* C2 Material Colors */
|
/* C2 Material Colors */
|
||||||
--c2-primary: #006397;
|
--c2-primary: #006397;
|
||||||
|
--c2-on-primary: #ffffff;
|
||||||
|
--c2-primary-container: #cce5ff;
|
||||||
|
--c2-on-primary-container: #001e31;
|
||||||
|
|
||||||
/* C3 Material Colors */
|
/* C3 Material Colors */
|
||||||
--c3-primary: #954170;
|
--c3-primary: #954170;
|
||||||
|
@ -5,6 +5,7 @@ module.exports = {
|
|||||||
colors: {
|
colors: {
|
||||||
transparent: 'transparent',
|
transparent: 'transparent',
|
||||||
current: 'currentColor',
|
current: 'currentColor',
|
||||||
|
white: "#ffffff",
|
||||||
|
|
||||||
"js-color": "var(--js-color)",
|
"js-color": "var(--js-color)",
|
||||||
"dark-color": "var(--dark-color)",
|
"dark-color": "var(--dark-color)",
|
||||||
@ -22,8 +23,14 @@ module.exports = {
|
|||||||
"code-bg-color": "var(--code-bg-color)",
|
"code-bg-color": "var(--code-bg-color)",
|
||||||
"code-color": "var(--code-color)",
|
"code-color": "var(--code-color)",
|
||||||
"border-color": "var(--border-color)",
|
"border-color": "var(--border-color)",
|
||||||
|
|
||||||
"c1-primary": "var(--c1-primary)",
|
"c1-primary": "var(--c1-primary)",
|
||||||
|
|
||||||
"c2-primary": "var(--c2-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-primary": "var(--c3-primary)",
|
||||||
"c3-on-primary": "var(--c3-on-primary)",
|
"c3-on-primary": "var(--c3-on-primary)",
|
||||||
"c3-primary-container": "var(--c3-primary-container)",
|
"c3-primary-container": "var(--c3-primary-container)",
|
||||||
@ -35,6 +42,9 @@ module.exports = {
|
|||||||
"c5-on-primary-container": "var(--c5-on-primary-container)",
|
"c5-on-primary-container": "var(--c5-on-primary-container)",
|
||||||
"bg-color": "var(--bg-color)",
|
"bg-color": "var(--bg-color)",
|
||||||
},
|
},
|
||||||
|
borderWidth: {
|
||||||
|
'1': '1px'
|
||||||
|
},
|
||||||
extend: {},
|
extend: {},
|
||||||
},
|
},
|
||||||
plugins: [],
|
plugins: [],
|
||||||
|
Loading…
Reference in New Issue
Block a user