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.
|
/// Consts are stored here.
|
||||||
pub globals: HashMap<GlobalId, Value>,
|
pub globals: HashMap<GlobalId, Value>,
|
||||||
|
|
||||||
|
pub user_values: HashMap<Symbol, Value>,
|
||||||
|
|
||||||
pub mappings: HashMap<GlobalId, HashMap<Value, Value>>,
|
pub mappings: HashMap<GlobalId, HashMap<Value, Value>>,
|
||||||
|
|
||||||
/// For each struct type, we only need to remember the names of its members, in order.
|
/// 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(),
|
values: Default::default(),
|
||||||
functions: Default::default(),
|
functions: Default::default(),
|
||||||
globals: Default::default(),
|
globals: Default::default(),
|
||||||
|
user_values: Default::default(),
|
||||||
mappings: Default::default(),
|
mappings: Default::default(),
|
||||||
structs: Default::default(),
|
structs: Default::default(),
|
||||||
contexts: Default::default(),
|
contexts: Default::default(),
|
||||||
@ -310,16 +313,15 @@ impl<'a> Cursor<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn lookup(&self, name: Symbol) -> Option<Value> {
|
fn lookup(&self, name: Symbol) -> Option<Value> {
|
||||||
let Some(context) = self.contexts.last() else {
|
if let Some(context) = self.contexts.last() {
|
||||||
panic!("lookup requires a context");
|
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);
|
self.user_values.get(&name).cloned()
|
||||||
if option_value.is_some() {
|
|
||||||
return option_value.cloned();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.globals.get(&GlobalId { program: context.program, name }).cloned()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lookup_mapping(&self, program: Option<Symbol>, name: Symbol) -> Option<&HashMap<Value, Value>> {
|
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()
|
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.
|
/// Execute the whole step of the current Element.
|
||||||
///
|
///
|
||||||
/// That is, perform a step, and then finish all statements and expressions that have been pushed,
|
/// 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 => {
|
Statement::Assign(assign) if step == 1 => {
|
||||||
let value = self.values.pop().unwrap();
|
let value = self.values.pop().unwrap();
|
||||||
let Expression::Identifier(id) = &assign.place else { tc_fail!() };
|
let Expression::Identifier(id) = &assign.place else { tc_fail!() };
|
||||||
self.contexts.set(id.name, value);
|
self.set_variable(id.name, value);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
Statement::Block(block) => return Ok(self.step_block(block, false, step)),
|
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 => {
|
Statement::Const(const_) if step == 1 => {
|
||||||
let value = self.pop_value()?;
|
let value = self.pop_value()?;
|
||||||
self.contexts.set(const_.place.name, value);
|
self.set_variable(const_.place.name, value);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
Statement::Definition(definition) if step == 0 => {
|
Statement::Definition(definition) if step == 0 => {
|
||||||
@ -504,7 +514,7 @@ impl<'a> Cursor<'a> {
|
|||||||
Statement::Definition(definition) if step == 1 => {
|
Statement::Definition(definition) if step == 1 => {
|
||||||
let value = self.pop_value()?;
|
let value = self.pop_value()?;
|
||||||
match &definition.place {
|
match &definition.place {
|
||||||
Expression::Identifier(id) => self.contexts.set(id.name, value),
|
Expression::Identifier(id) => self.set_variable(id.name, value),
|
||||||
Expression::Tuple(tuple) => {
|
Expression::Tuple(tuple) => {
|
||||||
let Value::Tuple(rhs) = value else {
|
let Value::Tuple(rhs) = value else {
|
||||||
tc_fail!();
|
tc_fail!();
|
||||||
@ -513,7 +523,7 @@ impl<'a> Cursor<'a> {
|
|||||||
let Expression::Identifier(id) = name else {
|
let Expression::Identifier(id) = name else {
|
||||||
tc_fail!();
|
tc_fail!();
|
||||||
};
|
};
|
||||||
self.contexts.set(id.name, val);
|
self.set_variable(id.name, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => tc_fail!(),
|
_ => tc_fail!(),
|
||||||
@ -542,7 +552,7 @@ impl<'a> Cursor<'a> {
|
|||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
let new_start = start.inc_wrapping();
|
let new_start = start.inc_wrapping();
|
||||||
self.contexts.set(iteration.variable.name, start);
|
self.set_variable(iteration.variable.name, start);
|
||||||
self.frames.push(Frame {
|
self.frames.push(Frame {
|
||||||
step: 0,
|
step: 0,
|
||||||
element: Element::Block { block: &iteration.block, function_body: false },
|
element: Element::Block { block: &iteration.block, function_body: false },
|
||||||
@ -906,15 +916,15 @@ impl<'a> Cursor<'a> {
|
|||||||
FunctionVariant::Leo(function) => {
|
FunctionVariant::Leo(function) => {
|
||||||
assert!(function.variant == Variant::AsyncFunction);
|
assert!(function.variant == Variant::AsyncFunction);
|
||||||
let len = self.values.len();
|
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(
|
self.contexts.push(
|
||||||
gid.program,
|
gid.program,
|
||||||
self.signer,
|
self.signer,
|
||||||
true, // is_async
|
true, // is_async
|
||||||
);
|
);
|
||||||
let param_names = function.input.iter().map(|input| input.identifier.name);
|
let param_names = function.input.iter().map(|input| input.identifier.name);
|
||||||
for (name, value) in param_names.zip(values_iter) {
|
for (name, value) in param_names.zip(values) {
|
||||||
self.contexts.set(name, value);
|
self.set_variable(name, value);
|
||||||
}
|
}
|
||||||
self.frames.last_mut().unwrap().step = 1;
|
self.frames.last_mut().unwrap().step = 1;
|
||||||
self.frames.push(Frame {
|
self.frames.push(Frame {
|
||||||
@ -995,7 +1005,7 @@ impl<'a> Cursor<'a> {
|
|||||||
self.contexts.push(function_program, caller, is_async);
|
self.contexts.push(function_program, caller, is_async);
|
||||||
let param_names = function.input.iter().map(|input| input.identifier.name);
|
let param_names = function.input.iter().map(|input| input.identifier.name);
|
||||||
for (name, value) in param_names.zip(arguments) {
|
for (name, value) in param_names.zip(arguments) {
|
||||||
self.contexts.set(name, value);
|
self.set_variable(name, value);
|
||||||
}
|
}
|
||||||
self.frames.push(Frame {
|
self.frames.push(Frame {
|
||||||
step: 0,
|
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;
|
#step to take one step towards evaluating the current expression or statement;
|
||||||
#over to complete evaluating the current expression or statement;
|
#over to complete evaluating the current expression or statement;
|
||||||
#run to finish evaluating
|
#run to finish evaluating
|
||||||
#quit to exit the interpreter.
|
#quit to quit the interpreter.
|
||||||
|
|
||||||
You can set a breakpoint with
|
You can set a breakpoint with
|
||||||
#break program_name line_number
|
#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 also use one letter abbreviations for these commands, such as #i.
|
||||||
|
|
||||||
You may simply enter expressions or statements on the command line
|
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");
|
std::io::stdin().read_line(&mut buffer).expect("read_line");
|
||||||
let action = match buffer.trim() {
|
let action = match buffer.trim() {
|
||||||
|
"" => continue,
|
||||||
"#i" | "#into" => InterpreterAction::Into,
|
"#i" | "#into" => InterpreterAction::Into,
|
||||||
"#s" | "#step" => InterpreterAction::Step,
|
"#s" | "#step" => InterpreterAction::Step,
|
||||||
"#o" | "#over" => InterpreterAction::Over,
|
"#o" | "#over" => InterpreterAction::Over,
|
||||||
|
Loading…
Reference in New Issue
Block a user