aboutsummaryrefslogtreecommitdiff
path: root/src/language.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/language.cc')
-rw-r--r--src/language.cc95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/language.cc b/src/language.cc
new file mode 100644
index 0000000..277c545
--- /dev/null
+++ b/src/language.cc
@@ -0,0 +1,95 @@
+// Copyright 2021 Benjamin Barenblat
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#include "src/language.h"
+
+#include <stdint.h>
+
+#include <memory>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "src/builtin.h"
+#include "third_party/abseil/absl/strings/str_cat.h"
+
+namespace ec {
+
+State::State() noexcept : environment(BuiltinEnvironment()) {}
+
+void GroundTerm::Evaluate(State& state) const noexcept {
+ state.stack.push_back(Clone());
+}
+
+std::string GroundTerm::Show() const noexcept {
+ // A double-precision value has 13 decimal digits of precision.
+ std::ostringstream s;
+ s.precision(13);
+ s << value_;
+ return s.str();
+}
+
+std::string GroundTerm::DebugString() const noexcept {
+ return absl::StrCat("GroundTerm(", value_, ")");
+}
+
+GroundTerm* GroundTerm::CloneImpl() const noexcept {
+ return new GroundTerm(*this);
+}
+
+void ForeignProgramTerm::Evaluate(State& state) const { impl_(state); }
+
+std::string ForeignProgramTerm::Show() const noexcept { return "<program>"; }
+
+std::string ForeignProgramTerm::DebugString() const noexcept {
+ return absl::StrCat("ForeignProgramTerm(", reinterpret_cast<uintptr_t>(impl_),
+ ")");
+}
+
+ForeignProgramTerm* ForeignProgramTerm::CloneImpl() const noexcept {
+ return new ForeignProgramTerm(*this);
+}
+
+void SymbolTerm::Evaluate(State& state) const {
+ auto it = state.environment.find(name_);
+ if (it == state.environment.end()) {
+ throw UndefinedName(name_);
+ }
+ it->second->Evaluate(state);
+}
+
+std::string SymbolTerm::Show() const noexcept {
+ return absl::StrCat("'", name_);
+}
+
+std::string SymbolTerm::DebugString() const noexcept {
+ return absl::StrCat("SymbolTerm(", name_, ")");
+}
+
+SymbolTerm* SymbolTerm::CloneImpl() const noexcept {
+ return new SymbolTerm(*this);
+}
+
+void FormatStackElement(std::string* out,
+ std::shared_ptr<const Term> term) noexcept {
+ out->append(term->Show());
+}
+
+void EvaluateAll(const Program& program, State& state) {
+ for (auto term : program) {
+ term->Evaluate(state);
+ }
+}
+
+} // namespace ec