mirror of
https://github.com/exoticorn/curlywas.git
synced 2026-01-20 11:46:43 +01:00
add support for 'if else', change hex escapes to '\ab'
This commit is contained in:
@@ -5,11 +5,20 @@ import "env.printChar" fn printChar(i32);
|
|||||||
export fn upd() {
|
export fn upd() {
|
||||||
printChar(12);
|
printChar(12);
|
||||||
printChar('Test');
|
printChar('Test');
|
||||||
printChar('\x1f\x10\x10');
|
printChar('\1f\10\10');
|
||||||
printChar('abc\n');
|
printChar('abc\n');
|
||||||
printString(0);
|
printString(0);
|
||||||
|
|
||||||
|
let t = 32!32 / 1000 #% 3;
|
||||||
|
if t == 0 {
|
||||||
|
printChar('one');
|
||||||
|
} else if t == 1 {
|
||||||
|
printChar('two');
|
||||||
|
} else {
|
||||||
|
printChar('many');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data 0 {
|
data 0 {
|
||||||
"\x0e\x64\"Colors!!!\"\x0e\1\0"
|
"\0e\64\"Colors!!!\"\0e\1\r\n\0"
|
||||||
}
|
}
|
||||||
@@ -310,7 +310,10 @@ fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = LexerError> {
|
|||||||
let s = parse_string_escapes(s);
|
let s = parse_string_escapes(s);
|
||||||
let mut value = 0;
|
let mut value = 0;
|
||||||
for (i, c) in s.chars().enumerate() {
|
for (i, c) in s.chars().enumerate() {
|
||||||
value |= (c as u32) << (i * 8);
|
// TODO: generate error on overflow
|
||||||
|
if i < 4 {
|
||||||
|
value |= (c as u32) << (i * 8);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Token::Int(value as i32)
|
Token::Int(value as i32)
|
||||||
});
|
});
|
||||||
@@ -397,37 +400,22 @@ fn map_token<O>(
|
|||||||
|
|
||||||
fn parse_string_escapes(s: String) -> String {
|
fn parse_string_escapes(s: String) -> String {
|
||||||
let mut result = String::new();
|
let mut result = String::new();
|
||||||
let mut chars = s.chars();
|
let mut chars = s.chars().peekable();
|
||||||
while let Some(c) = chars.next() {
|
while let Some(c) = chars.next() {
|
||||||
if c != '\\' {
|
if c != '\\' {
|
||||||
result.push(c);
|
result.push(c);
|
||||||
} else if let Some(c) = chars.next() {
|
} else if let Some(c) = chars.next() {
|
||||||
match c {
|
match c {
|
||||||
'0' => result.push('\0'),
|
'0'..='9' | 'a'..='f' | 'A'..='F' => {
|
||||||
|
let mut number = c.to_string();
|
||||||
|
if let Some('0'..='9' | 'a' ..= 'f' | 'A'..='F') = chars.peek() {
|
||||||
|
number.push(chars.next().unwrap());
|
||||||
|
}
|
||||||
|
result.push(u8::from_str_radix(&number, 16).unwrap() as char);
|
||||||
|
},
|
||||||
'n' => result.push('\n'),
|
'n' => result.push('\n'),
|
||||||
'r' => result.push('\r'),
|
'r' => result.push('\r'),
|
||||||
't' => result.push('\t'),
|
't' => result.push('\t'),
|
||||||
'x' => {
|
|
||||||
if let Some(high) = chars.next() {
|
|
||||||
if let Some(low) = chars.next() {
|
|
||||||
if let Ok(c) = u8::from_str_radix(&format!("{}{}", high, low), 16) {
|
|
||||||
result.push(c as char);
|
|
||||||
} else {
|
|
||||||
result.push('\\');
|
|
||||||
result.push('x');
|
|
||||||
result.push(high);
|
|
||||||
result.push(low);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result.push('\\');
|
|
||||||
result.push('x');
|
|
||||||
result.push(high);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result.push('\\');
|
|
||||||
result.push('x');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
other => result.push(other),
|
other => result.push(other),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -514,15 +502,25 @@ fn script_parser() -> impl Parser<Token, ast::Script, Error = ScriptError> + Clo
|
|||||||
block: Box::new(block),
|
block: Box::new(block),
|
||||||
});
|
});
|
||||||
|
|
||||||
let if_expr = just(Token::If)
|
let if_expr = recursive::<_, ast::Expr, _, _, _>(|if_expr| {
|
||||||
.ignore_then(expression.clone())
|
just(Token::If)
|
||||||
.then(block.clone())
|
.ignore_then(expression.clone())
|
||||||
.then(just(Token::Else).ignore_then(block.clone()).or_not())
|
.then(block.clone())
|
||||||
.map(|((condition, if_true), if_false)| ast::Expr::If {
|
.then(
|
||||||
condition: Box::new(condition),
|
just(Token::Else)
|
||||||
if_true: Box::new(if_true),
|
.ignore_then(
|
||||||
if_false: if_false.map(Box::new),
|
block
|
||||||
});
|
.clone()
|
||||||
|
.or(if_expr.map_with_span(|expr, span| expr.with_span(span))),
|
||||||
|
)
|
||||||
|
.or_not(),
|
||||||
|
)
|
||||||
|
.map(|((condition, if_true), if_false)| ast::Expr::If {
|
||||||
|
condition: Box::new(condition),
|
||||||
|
if_true: Box::new(if_true),
|
||||||
|
if_false: if_false.map(Box::new),
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
let block_expr = loop_expr.or(label_block_expr).or(if_expr).boxed();
|
let block_expr = loop_expr.or(label_block_expr).or(if_expr).boxed();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user