f753af7aa1ee — Leonard Ritter 9 months ago
* initial check-in table interface
12 files changed, 115 insertions(+), 217 deletions(-)

M genie.lua
M include/scopes/scopes.h
M src/error.hpp
M src/globals.cpp
R src/lifetime.cpp => 
R src/lifetime.hpp => 
M src/prover.cpp
M src/prover.hpp
M src/value.cpp
M src/value.hpp
M testing/test_all.sc
A => testing/test_table.sc
M genie.lua +0 -1
@@ 165,7 165,6 @@ project "scopesrt"
         "src/c_import.cpp",
         "src/execution.cpp",
         "src/prover.cpp",
-        "src/lifetime.cpp",
         "src/quote.cpp",
         "src/platform_abi.cpp",
         "src/gen_spirv.cpp",

          
M include/scopes/scopes.h +6 -0
@@ 264,6 264,12 @@ SCOPES_LIBEXPORT sc_valueref_t sc_label_
 SCOPES_LIBEXPORT void sc_label_set_body(sc_valueref_t label, sc_valueref_t body);
 SCOPES_LIBEXPORT sc_valueref_t sc_merge_new(sc_valueref_t label, sc_valueref_t value);
 
+// tables
+
+SCOPES_LIBEXPORT void sc_table_set_symbol(sc_valueref_t target, sc_symbol_t name, sc_valueref_t value);
+SCOPES_LIBEXPORT sc_valueref_raises_t sc_table_at(sc_valueref_t target, sc_symbol_t name);
+SCOPES_LIBEXPORT sc_symbol_valueref_tuple_t sc_table_next(sc_valueref_t target, sc_symbol_t key);
+
 // parsing
 
 SCOPES_LIBEXPORT sc_valueref_raises_t sc_parse_from_path(const sc_string_t *path);

          
M src/error.hpp +3 -0
@@ 428,6 428,9 @@ formatters:
     T(RTMissingLocalTypeAttribute, \
         "runtime: no attribute %0 in local type", \
         Symbol) \
+    T(RTMissingTableAttribute, \
+        "runtime: no attribute %0 in table", \
+        Symbol) \
     T(RTRegExError, \
         "runtime: error in regular expression: %0", \
         PString) \

          
M src/globals.cpp +51 -0
@@ 1559,6 1559,53 @@ sc_valueref_t sc_merge_new(sc_valueref_t
     return MergeTemplate::from(label.cast<LabelTemplate>(), value);
 }
 
+// Table
+////////////////////////////////////////////////////////////////////////////////
+
+void sc_table_set_symbol(sc_valueref_t target, sc_symbol_t name, sc_valueref_t value) {
+    using namespace scopes;
+    auto &&ctx = active_ast_context();
+    assert(ctx.block);
+    auto &&table = ctx.block->get_table(ValueIndex(target.cast<TypedValue>()));
+    table.replace(name, value.cast<Const>());
+}
+
+sc_valueref_raises_t sc_table_at(sc_valueref_t target, sc_symbol_t name) {
+    using namespace scopes;
+    SCOPES_RESULT_TYPE(ValueRef);
+    auto &&ctx = active_ast_context();
+    assert(ctx.block);
+    auto &&table = ctx.block->get_table(ValueIndex(target.cast<TypedValue>()));
+    auto index = table.find_index(name);
+    if (index < 0) {
+        SCOPES_C_ERROR(RTMissingTableAttribute, name);
+    }
+    SCOPES_C_RETURN(table.values[index]);
+}
+
+sc_symbol_valueref_tuple_t sc_table_next(sc_valueref_t target, sc_symbol_t key) {
+    using namespace scopes;
+    using namespace scopes;
+    auto &&ctx = active_ast_context();
+    assert(ctx.block);
+    auto &&map = ctx.block->get_table(ValueIndex(target.cast<TypedValue>()));
+    int index;
+    int count = map.keys.size();
+    if (key == SYM_Unnamed) {
+        index = 0;
+    } else {
+        index = map.find_index(key);
+        if (index < 0)
+            index = count;
+        else
+            index++;
+    }
+    if (index != count) {
+        return { map.keys[index], map.values[index] };
+    }
+    return { SYM_Unnamed, ValueRef() };
+}
+
 // Parser
 ////////////////////////////////////////////////////////////////////////////////
 

          
@@ 2255,6 2302,10 @@ void init_globals(int argc, char *argv[]
     DEFINE_EXTERN_C_FUNCTION(sc_label_set_body, _void, TYPE_ValueRef, TYPE_ValueRef);
     DEFINE_EXTERN_C_FUNCTION(sc_merge_new, TYPE_ValueRef, TYPE_ValueRef, TYPE_ValueRef);
 
+    DEFINE_EXTERN_C_FUNCTION(sc_table_set_symbol, _void, TYPE_ValueRef, TYPE_Symbol, TYPE_ValueRef);
+    DEFINE_RAISING_EXTERN_C_FUNCTION(sc_table_at, TYPE_ValueRef, TYPE_ValueRef, TYPE_Symbol);
+    DEFINE_RAISING_EXTERN_C_FUNCTION(sc_table_next, arguments_type({TYPE_Symbol, TYPE_ValueRef}), TYPE_ValueRef, TYPE_Symbol);
+
     DEFINE_EXTERN_C_FUNCTION(sc_is_file, TYPE_Bool, TYPE_String);
     DEFINE_EXTERN_C_FUNCTION(sc_is_directory, TYPE_Bool, TYPE_String);
     DEFINE_EXTERN_C_FUNCTION(sc_realpath, TYPE_String, TYPE_String);

          
R src/lifetime.cpp =>  +0 -184
@@ 1,184 0,0 @@ 
-/*
-    The Scopes Compiler Infrastructure
-    This file is distributed under the MIT License.
-    See LICENSE.md for details.
-*/
-
-#include "lifetime.hpp"
-#include "value.hpp"
-#include "prover.hpp"
-#include "error.hpp"
-
-namespace scopes {
-
-#define HANDLER(CLASS) \
-    SCOPES_RESULT(void) tag_ ## CLASS(const ASTContext &ctx, const CLASS ## Ref &node)
-
-HANDLER(Merge) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(Repeat) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(Return) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(Raise) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(Unreachable) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(Discard) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(Label) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(LoopLabel) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(CondBr) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(Switch) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(Call) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(Select) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(ExtractValue) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(InsertValue) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(GetElementPtr) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(ExtractElement) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(InsertElement) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(ShuffleVector) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(Alloca) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(Malloc) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(Free) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(Load) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(Store) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(ICmp) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(FCmp) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(UnOp) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(BinOp) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(TriOp) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(Annotate) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(Sample) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(ImageQuerySize) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(ImageQueryLod) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(ImageQueryLevels) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(ImageQuerySamples) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(ImageRead) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(ImageWrite) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(ExecutionMode) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-HANDLER(Cast) {
-    //SCOPES_RESULT_TYPE(void);
-    return {};
-}
-
-SCOPES_RESULT(void) tag_instruction(const ASTContext &ctx, const InstructionRef &node) {
-    SCOPES_RESULT_TYPE(void);
-    switch(node->kind()) {
-#define T(NAME, BNAME, CLASS) \
-    case NAME: SCOPES_CHECK_RESULT(tag_ ## CLASS(ctx, node.cast<CLASS>())); break;
-    SCOPES_INSTRUCTION_VALUE_KIND()
-#undef T
-    default: assert(false);
-    }
-    return {};
-}
-
-#undef HANDLER
-
-} // namespace scopes

          
R src/lifetime.hpp =>  +0 -21
@@ 1,21 0,0 @@ 
-/*
-    The Scopes Compiler Infrastructure
-    This file is distributed under the MIT License.
-    See LICENSE.md for details.
-*/
-
-#ifndef SCOPES_LIFETIME_HPP
-#define SCOPES_LIFETIME_HPP
-
-#include "result.hpp"
-#include "valueref.inc"
-
-namespace scopes {
-
-struct ASTContext;
-
-SCOPES_RESULT(void) tag_instruction(const ASTContext &ctx, const InstructionRef &node);
-
-} // namespace scopes
-
-#endif // SCOPES_LIFETIME_HPP

          
M src/prover.cpp +5 -2
@@ 26,7 26,6 @@ 
 #include "scopes/scopes.h"
 #include "qualifier.inc"
 #include "symbol_enum.inc"
-#include "lifetime.hpp"
 
 #include <algorithm>
 #include <unordered_set>

          
@@ 264,7 263,6 @@ SCOPES_RESULT(void) ASTContext::append(c
     SCOPES_RESULT_TYPE(void);
     assert(block);
     block->append(value);
-    SCOPES_CHECK_RESULT(tag_instruction(*this, value));
     return {};
 }
 

          
@@ 2635,6 2633,11 @@ SCOPES_RESULT(FunctionRef) prove(const F
     return result;
 }
 
+const ASTContext &active_ast_context() {
+    assert(ast_context);
+    return *ast_context;
+}
+
 SCOPES_RESULT(TypedValueRef) prove(const ValueRef &node) {
     SCOPES_RESULT_TYPE(TypedValueRef);
     if (!ast_context) {

          
M src/prover.hpp +2 -0
@@ 79,6 79,8 @@ SCOPES_RESULT(FunctionRef) prove(const F
 SCOPES_RESULT(TypedValueRef) prove(const ASTContext &ctx, const ValueRef &node);
 SCOPES_RESULT(TypedValueRef) prove(const ValueRef &node);
 
+const ASTContext &active_ast_context();
+
 SCOPES_RESULT(const Type *) ptr_to_ref(const Type *T);
 SCOPES_RESULT(const Type *) ref_to_ptr(const Type *T);
 

          
M src/value.cpp +16 -6
@@ 627,11 627,24 @@ void Block::set_parent(Block *_parent) {
     assert(_parent);
     depth = _parent->depth + 1;
     tag_traceback = _parent->tag_traceback;
+    merge_table_from(*_parent);
+}
+
+void Block::merge_table_from(Block &source) {
+    for (auto &&table_entry : source.tables) {
+        auto &&src = table_entry.second;
+        auto &&dst = get_table(table_entry.first);
+        int sz = src.keys.size();
+        for (int i = 0; i < sz; ++i) {
+            dst.replace(src.keys[i], src.values[i]);
+        }
+    }
 }
 
 void Block::clear() {
     body.clear();
     terminator = InstructionRef();
+    tables.clear();
 }
 
 void Block::migrate_from(Block &source) {

          
@@ 643,6 656,7 @@ void Block::migrate_from(Block &source) 
         terminator = source.terminator;
         terminator->block = this;
     }
+    merge_table_from(source);
 }
 
 bool Block::empty() const {

          
@@ 671,12 685,8 @@ void Block::append(const InstructionRef 
     }
 }
 
-Block::DataMap &Block::get_channel(Symbol name) {
-    DataMap *&map = channels[name];
-    if (!map) {
-        map = new DataMap();
-    }
-    return *map;
+Table &Block::get_table(const ValueIndex &value) {
+    return tables[value];
 }
 
 //------------------------------------------------------------------------------

          
M src/value.hpp +6 -3
@@ 111,13 111,16 @@ protected:
 
 //------------------------------------------------------------------------------
 
+typedef OrderedMap<ConstRef> Table;
+
 struct Block {
-    typedef std::unordered_map<TypedValue *, ConstRef> DataMap;
+    typedef std::unordered_map<ValueIndex, Table, ValueIndex::Hash> Tables;
 
     Block();
     void append(const InstructionRef &node);
     bool empty() const;
     void migrate_from(Block &source);
+    void merge_table_from(Block &source);
     void clear();
     void set_parent(Block *parent);
 

          
@@ 126,9 129,9 @@ struct Block {
     void insert_at(int index);
     void insert_at_end();
 
-    DataMap &get_channel(Symbol name);
+    Table &get_table(const ValueIndex &value);
 
-    std::unordered_map<Symbol, DataMap *, Symbol::Hash> channels;
+    Tables tables;
 
     int depth;
     int insert_index;

          
M testing/test_all.sc +1 -0
@@ 77,6 77,7 @@ test-modules
     .test_struct
     .test_sugar
     .test_switch
+    .test_table
     .test_testing
     .test_try
     .test_tuple_array

          
A => testing/test_table.sc +25 -0
@@ 0,0 1,25 @@ 
+
+spice tset (target key value)
+    if (not ('constant? value))
+        error "value must be constant"
+    sc_table_set_symbol target (key as Symbol) value
+
+spice tget (target key)
+    sc_table_at target (key as Symbol)
+
+run-stage;
+
+local k = 1
+
+tset k 'test 1
+if true
+    tset k 'test 2
+    dump (tget k 'test)
+else
+    tset k 'test 3
+    dump (tget k 'test)
+
+dump (tget k 'test)
+
+
+;
  No newline at end of file