toctave

t(iny)octave
git clone https://0xff.ir/g/toctave.git
Log | Files | Refs | README

env.cpp (1164B)


      1 // Runtime environment
      2 
      3 // Copyright (C) 2022, Mohammad-Reza Nabipoor
      4 // SPDX-License-Identifier: GPL-3.0-or-later
      5 
      6 #include "env.hpp"
      7 
      8 #include <algorithm>
      9 #include <cassert>
     10 #include <utility>
     11 
     12 namespace {
     13 
     14 using VarIter = env::Env::iterator;
     15 
     16 std::pair<bool, VarIter>
     17 vars_find(env::Env& env, const std::string& name)
     18 {
     19   auto f{ std::begin(env) };
     20   auto l{ std::end(env) };
     21   auto it{ std::lower_bound(
     22     f, l, name, [](const auto& x, const auto& y) { return x.name < y; }) };
     23 
     24   return std::make_pair(it != l, it);
     25 }
     26 
     27 } // anonymous namespace
     28 
     29 extern "C" bool
     30 toctave_var(void* env, const char* name, double* val)
     31 {
     32   assert(env);
     33 
     34   std::string n{ name };
     35   auto [found, it] = vars_find(*reinterpret_cast<env::Env*>(env), n);
     36 
     37   if (!found)
     38     return false;
     39 
     40   auto& var{ *it };
     41 
     42   assert(var.name == n);
     43   if (val)
     44     *val = var.val;
     45   return true;
     46 }
     47 
     48 extern "C" void
     49 toctave_var_set(void* environ, const char* name, double val)
     50 {
     51   assert(environ);
     52 
     53   auto& env{ *reinterpret_cast<env::Env*>(environ) };
     54   std::string n{ name };
     55   auto [found, it] = vars_find(env, n);
     56 
     57   if (found)
     58     it->val = val;
     59   else
     60     env.insert(it, env::Var{ n, val });
     61 }