blob: a7b4a6b6ca0547068e1b0f6977439a5121824716 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_DEVELOPER_SHELL_INTERPRETER_SRC_INSTRUCTIONS_H_
#define SRC_DEVELOPER_SHELL_INTERPRETER_SRC_INSTRUCTIONS_H_
#include <memory>
#include <ostream>
#include <string>
#include <string_view>
#include "src/developer/shell/interpreter/src/code.h"
#include "src/developer/shell/interpreter/src/nodes.h"
namespace shell {
namespace interpreter {
// Defines a variable or a constant. Depending on the container, this can be a global or a local
// variable.
class VariableDefinition : public Instruction {
public:
VariableDefinition(Interpreter* interpreter, uint64_t file_id, uint64_t node_id,
std::string_view name, std::unique_ptr<Type> type, bool is_mutable,
std::unique_ptr<Expression> initial_value = nullptr)
: Instruction(interpreter, file_id, node_id),
name_(name),
type_(std::move(type)),
is_mutable_(is_mutable),
initial_value_(std::move(initial_value)) {}
const std::string& name() const { return name_; }
const Type* type() const { return type_.get(); }
bool is_mutable() const { return is_mutable_; }
const Expression* initial_value() const { return initial_value_.get(); }
size_t index() const { return index_; }
const VariableDefinition* AsVariableDefinition() const override { return this; }
void Dump(std::ostream& os) const override;
void Compile(ExecutionContext* context, code::Code* code) override;
private:
// Name of the variable.
const std::string name_;
// Type of the variable. It can be the undefined type. In that case, the initial value must be
// defined.
std::unique_ptr<Type> type_;
// True if the value associated with this variable can be modified after the variable creation.
const bool is_mutable_;
// The initial value for the variable. If the variable is not mutable or if the type is
// undefined then the initial value must be specified.
std::unique_ptr<Expression> initial_value_;
// Index (in bytes) of the variable relative to the execution scope which defines it.
size_t index_ = 0;
};
// Emits a result. A value is computed and then sent back to the client using OnResult.
class EmitResult : public Instruction {
public:
EmitResult(Interpreter* interpreter, uint64_t file_id, uint64_t node_id,
std::unique_ptr<Expression> expression)
: Instruction(interpreter, file_id, node_id), expression_(std::move(expression)) {}
const Expression* expression() const { return expression_.get(); }
void Dump(std::ostream& os) const override;
void Compile(ExecutionContext* context, code::Code* code) override;
private:
// The expression we want to compute and send back to the client.
std::unique_ptr<Expression> expression_;
};
class Assignment : public Instruction {
public:
Assignment(Interpreter* interpreter, uint64_t file_id, uint64_t node_id,
std::unique_ptr<Expression> destination, std::unique_ptr<Expression> source)
: Instruction(interpreter, file_id, node_id),
destination_(std::move(destination)),
source_(std::move(source)) {}
const Expression* destination() const { return destination_.get(); }
const Expression* source() const { return source_.get(); }
void Dump(std::ostream& os) const override;
void Compile(ExecutionContext* context, code::Code* code) override;
private:
std::unique_ptr<Expression> destination_;
std::unique_ptr<Expression> source_;
};
} // namespace interpreter
} // namespace shell
#endif // SRC_DEVELOPER_SHELL_INTERPRETER_SRC_INSTRUCTIONS_H_