Work on documentation
This commit is contained in:
@@ -61,7 +61,13 @@ fn tokenize(input: &str) -> Vec<Token> {
|
||||
continue;
|
||||
}
|
||||
// single ; is a word, create token
|
||||
tokens.push(Token::Word(";".to_string(), SourceSpan { start: pos, end: pos + 1 }));
|
||||
tokens.push(Token::Word(
|
||||
";".to_string(),
|
||||
SourceSpan {
|
||||
start: pos,
|
||||
end: pos + 1,
|
||||
},
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -96,15 +102,33 @@ fn compile(tokens: &[Token], dict: &Dictionary) -> Result<Vec<Op>, String> {
|
||||
|
||||
while i < tokens.len() {
|
||||
match &tokens[i] {
|
||||
Token::Int(n, span) => ops.push(Op::PushInt(*n, Some(*span))),
|
||||
Token::Float(f, span) => ops.push(Op::PushFloat(*f, Some(*span))),
|
||||
Token::Int(n, span) => {
|
||||
let key = n.to_string();
|
||||
if let Some(body) = dict.lock().unwrap().get(&key).cloned() {
|
||||
ops.extend(body);
|
||||
} else {
|
||||
ops.push(Op::PushInt(*n, Some(*span)));
|
||||
}
|
||||
}
|
||||
Token::Float(f, span) => {
|
||||
let key = f.to_string();
|
||||
if let Some(body) = dict.lock().unwrap().get(&key).cloned() {
|
||||
ops.extend(body);
|
||||
} else {
|
||||
ops.push(Op::PushFloat(*f, Some(*span)));
|
||||
}
|
||||
}
|
||||
Token::Str(s, span) => ops.push(Op::PushStr(s.clone(), Some(*span))),
|
||||
Token::Word(w, span) => {
|
||||
let word = w.as_str();
|
||||
if word == "{" {
|
||||
let (quote_ops, consumed, end_span) = compile_quotation(&tokens[i + 1..], dict)?;
|
||||
let (quote_ops, consumed, end_span) =
|
||||
compile_quotation(&tokens[i + 1..], dict)?;
|
||||
i += consumed;
|
||||
let body_span = SourceSpan { start: span.start, end: end_span.end };
|
||||
let body_span = SourceSpan {
|
||||
start: span.start,
|
||||
end: end_span.end,
|
||||
};
|
||||
ops.push(Op::Quotation(quote_ops, Some(body_span)));
|
||||
} else if word == "}" {
|
||||
return Err("unexpected }".into());
|
||||
@@ -115,7 +139,8 @@ fn compile(tokens: &[Token], dict: &Dictionary) -> Result<Vec<Op>, String> {
|
||||
} else if word == ";" {
|
||||
return Err("unexpected ;".into());
|
||||
} else if word == "if" {
|
||||
let (then_ops, else_ops, consumed, then_span, else_span) = compile_if(&tokens[i + 1..], dict)?;
|
||||
let (then_ops, else_ops, consumed, then_span, else_span) =
|
||||
compile_if(&tokens[i + 1..], dict)?;
|
||||
i += consumed;
|
||||
if else_ops.is_empty() {
|
||||
ops.push(Op::BranchIfZero(then_ops.len(), then_span, None));
|
||||
@@ -137,7 +162,10 @@ fn compile(tokens: &[Token], dict: &Dictionary) -> Result<Vec<Op>, String> {
|
||||
Ok(ops)
|
||||
}
|
||||
|
||||
fn compile_quotation(tokens: &[Token], dict: &Dictionary) -> Result<(Vec<Op>, usize, SourceSpan), String> {
|
||||
fn compile_quotation(
|
||||
tokens: &[Token],
|
||||
dict: &Dictionary,
|
||||
) -> Result<(Vec<Op>, usize, SourceSpan), String> {
|
||||
let mut depth = 1;
|
||||
let mut end_idx = None;
|
||||
|
||||
@@ -172,13 +200,18 @@ fn token_span(tok: &Token) -> Option<SourceSpan> {
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_colon_def(tokens: &[Token], dict: &Dictionary) -> Result<(usize, String, Vec<Op>), String> {
|
||||
fn compile_colon_def(
|
||||
tokens: &[Token],
|
||||
dict: &Dictionary,
|
||||
) -> Result<(usize, String, Vec<Op>), String> {
|
||||
if tokens.is_empty() {
|
||||
return Err("expected word name after ':'".into());
|
||||
}
|
||||
let name = match &tokens[0] {
|
||||
Token::Word(w, _) => w.clone(),
|
||||
_ => return Err("expected word name after ':'".into()),
|
||||
Token::Int(n, _) => n.to_string(),
|
||||
Token::Float(f, _) => f.to_string(),
|
||||
Token::Str(s, _) => s.clone(),
|
||||
};
|
||||
let mut semi_pos = None;
|
||||
for (i, tok) in tokens[1..].iter().enumerate() {
|
||||
@@ -198,11 +231,26 @@ fn compile_colon_def(tokens: &[Token], dict: &Dictionary) -> Result<(usize, Stri
|
||||
fn tokens_span(tokens: &[Token]) -> Option<SourceSpan> {
|
||||
let first = tokens.first().and_then(token_span)?;
|
||||
let last = tokens.last().and_then(token_span)?;
|
||||
Some(SourceSpan { start: first.start, end: last.end })
|
||||
Some(SourceSpan {
|
||||
start: first.start,
|
||||
end: last.end,
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn compile_if(tokens: &[Token], dict: &Dictionary) -> Result<(Vec<Op>, Vec<Op>, usize, Option<SourceSpan>, Option<SourceSpan>), String> {
|
||||
fn compile_if(
|
||||
tokens: &[Token],
|
||||
dict: &Dictionary,
|
||||
) -> Result<
|
||||
(
|
||||
Vec<Op>,
|
||||
Vec<Op>,
|
||||
usize,
|
||||
Option<SourceSpan>,
|
||||
Option<SourceSpan>,
|
||||
),
|
||||
String,
|
||||
> {
|
||||
let mut depth = 1;
|
||||
let mut else_pos = None;
|
||||
let mut then_pos = None;
|
||||
|
||||
Reference in New Issue
Block a user