adding map access was easy

This commit is contained in:
Shautvast 2025-11-10 11:09:55 +01:00
parent cbc7f6ce7a
commit 6f4824efac
6 changed files with 41 additions and 40 deletions

View file

@ -520,35 +520,39 @@ impl AstCompiler {
) -> Result<Expression, CompilerErrorAtLine> {
let get = (match &operand {
Expression::Map { .. } => MapGet {
map: Box::new(operand),
key: Box::new(index),
},
Expression::List { .. } => ListGet {
list: Box::new(operand),
index: Box::new(index),
},
Variable { var_type, .. } => {
if var_type == &ListType {
ListGet {
list: Box::new(operand),
index: Box::new(index),
}
} else {
Variable { var_type, .. } => match var_type {
ListType => ListGet {
list: Box::new(operand),
index: Box::new(index),
},
MapType => MapGet {
map: Box::new(operand),
key: Box::new(index),
},
_ => {
return Err(self.raise(CompilerError::IllegalTypeToIndex(var_type.to_string())));
}
}
},
_ => return Err(self.raise(CompilerError::IllegalTypeToIndex("Unknown".to_string()))),
});
self.consume(RightBracket, Expected("']' after index."))?;
Ok(get)
}
// work in progress
fn field(
&mut self,
operand: Expression,
_operand: Expression,
index: Token,
) -> Result<Expression, CompilerErrorAtLine> {
//TODO?
Ok(Expression::FieldGet {
Ok(FieldGet {
field: index.lexeme.clone(),
})
}
@ -635,7 +639,7 @@ impl AstCompiler {
&self.previous().lexeme,
"%Y-%m-%d %H:%M:%S%.3f %z",
)
.map_err(|e| self.raise(ParseError(self.previous().lexeme.clone())))?
.map_err(|_| self.raise(ParseError(self.previous().lexeme.clone())))?
.into(),
),
}
@ -945,6 +949,7 @@ pub enum Expression {
value: Box<Expression>,
},
MapGet {
map: Box<Expression>,
key: Box<Expression>,
},
ListGet {

View file

@ -102,17 +102,11 @@ impl Compiler {
self.current_line = statement.line();
match statement {
Statement::VarStmt {
name,
var_type,
initializer,
name, initializer, ..
} => {
let name = name.lexeme.as_str();
let var = symbols.get(name);
if let Some(Symbol::Variable {
var_type,
..
}) = var
{
if let Some(Symbol::Variable { var_type, .. }) = var {
let inferred_type = infer_type(initializer, symbols);
let calculated_type = calculate_type(var_type, &inferred_type)
.map_err(|e| CompilerErrorAtLine::raise(e, statement.line()))?;
@ -189,13 +183,7 @@ impl Compiler {
.find_constant(&name)
.unwrap_or_else(|| self.chunk.add_constant(Value::String(name.to_string())));
let function = symbols.get(name);
if let Some(Symbol::Function {
name,
parameters,
return_type,
body,
}) = function
{
if let Some(Symbol::Function { parameters, .. }) = function {
for parameter in parameters {
for argument in arguments {
if let NamedParameter { name, .. } = argument {
@ -295,7 +283,7 @@ impl Compiler {
Expression::Stop { .. } => {}
// Expression::PathMatch { line, .. } => {}
NamedParameter { .. } => {}
Expression::ListGet { index, list} => {
Expression::ListGet { index, list } => {
self.compile_expression(namespace, list, symbols, registry)?;
self.compile_expression(namespace, index, symbols, registry)?;
self.emit_byte(OP_LIST_GET);

View file

@ -2,7 +2,7 @@
mod tests {
use crate::value::Value;
use crate::{compile, run};
use chrono::{DateTime};
use chrono::DateTime;
#[test]
fn literal_int() {
@ -42,8 +42,11 @@ mod tests {
#[test]
fn index_in_list_as_var() {
assert_eq!(run(r#"let a:list = ["abc","def"]
a[1]"#), Ok(Value::String("def".into())))
assert_eq!(
run(r#"let a:list = ["abc","def"]
a[1]"#),
Ok(Value::String("def".into()))
)
}
#[test]
@ -163,7 +166,7 @@ object Person:
}
#[test]
fn define_map() {
fn assign_map() {
let result = run(r#"let m = {"name": "Dent"}
m"#);
@ -176,6 +179,17 @@ m"#);
}
}
#[test]
fn access_map() {
let result = run(r#"let m = {"name": "Dent"}
m["name"]"#);
let result = result.unwrap();
if let Value::String(v) = result {
assert_eq!(v.as_str(), "Dent");
}
}
#[test]
fn keyword_error() {
let result = run(r#"let map = {"name": "Dent"}"#);

View file

@ -49,8 +49,6 @@ pub fn start(registry: Arc<ArcSwap<HashMap<String, Chunk>>>) -> Result<(), CrudL
// break;
// }
}
// println!("-- Crudlang -- REPL exited");
Ok(())
}
fn list_endpoints(registry: Arc<HashMap<String, Chunk>>) {

View file

@ -38,11 +38,7 @@ fn make_qname(path: &str, name: &Token) -> String {
pub fn build(path: &str, ast: &[Statement], symbols: &mut HashMap<String, Symbol>) {
for statement in ast {
match statement {
Statement::VarStmt {
name,
var_type,
initializer,
} => {
Statement::VarStmt { name, var_type, .. } => {
let key = make_qname(path, name);
if !symbols.contains_key(&key) {
// surely there's a better way to do this?

View file

@ -1,5 +1,5 @@
use crate::errors::ValueError;
use chrono::{DateTime, Local, Utc};
use chrono::{DateTime, Utc};
use std::cmp::Ordering;
use std::collections::HashMap;
use std::fmt::{Display, Formatter};