mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-25 21:16:41 +03:00
setting top level values
This commit is contained in:
parent
334881cef5
commit
94638be01a
@ -245,6 +245,8 @@ pub struct Cursor<'a> {
|
||||
/// Consts are stored here.
|
||||
pub globals: HashMap<GlobalId, Value>,
|
||||
|
||||
pub user_values: HashMap<Symbol, Value>,
|
||||
|
||||
pub mappings: HashMap<GlobalId, HashMap<Value, Value>>,
|
||||
|
||||
/// For each struct type, we only need to remember the names of its members, in order.
|
||||
@ -271,6 +273,7 @@ impl<'a> Cursor<'a> {
|
||||
values: Default::default(),
|
||||
functions: Default::default(),
|
||||
globals: Default::default(),
|
||||
user_values: Default::default(),
|
||||
mappings: Default::default(),
|
||||
structs: Default::default(),
|
||||
contexts: Default::default(),
|
||||
@ -310,16 +313,15 @@ impl<'a> Cursor<'a> {
|
||||
}
|
||||
|
||||
fn lookup(&self, name: Symbol) -> Option<Value> {
|
||||
let Some(context) = self.contexts.last() else {
|
||||
panic!("lookup requires a context");
|
||||
if let Some(context) = self.contexts.last() {
|
||||
let option_value =
|
||||
context.names.get(&name).or_else(|| self.globals.get(&GlobalId { program: context.program, name }));
|
||||
if option_value.is_some() {
|
||||
return option_value.cloned();
|
||||
}
|
||||
};
|
||||
|
||||
let option_value = context.names.get(&name);
|
||||
if option_value.is_some() {
|
||||
return option_value.cloned();
|
||||
}
|
||||
|
||||
self.globals.get(&GlobalId { program: context.program, name }).cloned()
|
||||
self.user_values.get(&name).cloned()
|
||||
}
|
||||
|
||||
pub fn lookup_mapping(&self, program: Option<Symbol>, name: Symbol) -> Option<&HashMap<Value, Value>> {
|
||||
@ -340,6 +342,14 @@ impl<'a> Cursor<'a> {
|
||||
self.functions.get(&GlobalId { program, name }).cloned()
|
||||
}
|
||||
|
||||
fn set_variable(&mut self, symbol: Symbol, value: Value) {
|
||||
if self.contexts.len() > 0 {
|
||||
self.contexts.set(symbol, value);
|
||||
} else {
|
||||
self.user_values.insert(symbol, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// Execute the whole step of the current Element.
|
||||
///
|
||||
/// That is, perform a step, and then finish all statements and expressions that have been pushed,
|
||||
@ -462,7 +472,7 @@ impl<'a> Cursor<'a> {
|
||||
Statement::Assign(assign) if step == 1 => {
|
||||
let value = self.values.pop().unwrap();
|
||||
let Expression::Identifier(id) = &assign.place else { tc_fail!() };
|
||||
self.contexts.set(id.name, value);
|
||||
self.set_variable(id.name, value);
|
||||
true
|
||||
}
|
||||
Statement::Block(block) => return Ok(self.step_block(block, false, step)),
|
||||
@ -494,7 +504,7 @@ impl<'a> Cursor<'a> {
|
||||
}
|
||||
Statement::Const(const_) if step == 1 => {
|
||||
let value = self.pop_value()?;
|
||||
self.contexts.set(const_.place.name, value);
|
||||
self.set_variable(const_.place.name, value);
|
||||
true
|
||||
}
|
||||
Statement::Definition(definition) if step == 0 => {
|
||||
@ -504,7 +514,7 @@ impl<'a> Cursor<'a> {
|
||||
Statement::Definition(definition) if step == 1 => {
|
||||
let value = self.pop_value()?;
|
||||
match &definition.place {
|
||||
Expression::Identifier(id) => self.contexts.set(id.name, value),
|
||||
Expression::Identifier(id) => self.set_variable(id.name, value),
|
||||
Expression::Tuple(tuple) => {
|
||||
let Value::Tuple(rhs) = value else {
|
||||
tc_fail!();
|
||||
@ -513,7 +523,7 @@ impl<'a> Cursor<'a> {
|
||||
let Expression::Identifier(id) = name else {
|
||||
tc_fail!();
|
||||
};
|
||||
self.contexts.set(id.name, val);
|
||||
self.set_variable(id.name, val);
|
||||
}
|
||||
}
|
||||
_ => tc_fail!(),
|
||||
@ -542,7 +552,7 @@ impl<'a> Cursor<'a> {
|
||||
true
|
||||
} else {
|
||||
let new_start = start.inc_wrapping();
|
||||
self.contexts.set(iteration.variable.name, start);
|
||||
self.set_variable(iteration.variable.name, start);
|
||||
self.frames.push(Frame {
|
||||
step: 0,
|
||||
element: Element::Block { block: &iteration.block, function_body: false },
|
||||
@ -906,15 +916,15 @@ impl<'a> Cursor<'a> {
|
||||
FunctionVariant::Leo(function) => {
|
||||
assert!(function.variant == Variant::AsyncFunction);
|
||||
let len = self.values.len();
|
||||
let values_iter = self.values.drain(len - function.input.len()..);
|
||||
let values: Vec<Value> = self.values.drain(len - function.input.len()..).collect();
|
||||
self.contexts.push(
|
||||
gid.program,
|
||||
self.signer,
|
||||
true, // is_async
|
||||
);
|
||||
let param_names = function.input.iter().map(|input| input.identifier.name);
|
||||
for (name, value) in param_names.zip(values_iter) {
|
||||
self.contexts.set(name, value);
|
||||
for (name, value) in param_names.zip(values) {
|
||||
self.set_variable(name, value);
|
||||
}
|
||||
self.frames.last_mut().unwrap().step = 1;
|
||||
self.frames.push(Frame {
|
||||
@ -995,7 +1005,7 @@ impl<'a> Cursor<'a> {
|
||||
self.contexts.push(function_program, caller, is_async);
|
||||
let param_names = function.input.iter().map(|input| input.identifier.name);
|
||||
for (name, value) in param_names.zip(arguments) {
|
||||
self.contexts.set(name, value);
|
||||
self.set_variable(name, value);
|
||||
}
|
||||
self.frames.push(Frame {
|
||||
step: 0,
|
||||
|
@ -399,11 +399,14 @@ Once a function is running, commands include
|
||||
#step to take one step towards evaluating the current expression or statement;
|
||||
#over to complete evaluating the current expression or statement;
|
||||
#run to finish evaluating
|
||||
#quit to exit the interpreter.
|
||||
#quit to quit the interpreter.
|
||||
|
||||
You can set a breakpoint with
|
||||
#break program_name line_number
|
||||
|
||||
When executing Aleo VM code, you can print the value of a register like this:
|
||||
#print 2
|
||||
|
||||
You may also use one letter abbreviations for these commands, such as #i.
|
||||
|
||||
You may simply enter expressions or statements on the command line
|
||||
@ -541,6 +544,7 @@ pub fn interpret(
|
||||
}
|
||||
std::io::stdin().read_line(&mut buffer).expect("read_line");
|
||||
let action = match buffer.trim() {
|
||||
"" => continue,
|
||||
"#i" | "#into" => InterpreterAction::Into,
|
||||
"#s" | "#step" => InterpreterAction::Step,
|
||||
"#o" | "#over" => InterpreterAction::Over,
|
||||
|
Loading…
Reference in New Issue
Block a user