diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 98ee3ef4..493556af 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -33,7 +33,7 @@ jobs: steps: - uses: actions/checkout@v2 - run: sudo apt -qq update - - run: sudo apt install -y ant re2c + - run: sudo apt install -y ant re2c autoconf2.69 - run: git clone https://github.com/lmntal/lmntal-compiler.git - run: cd lmntal-compiler && ant && cd .. - run: ./autogen.sh diff --git a/NEWS b/NEWS index cd11246d..c5a5bed4 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +SLIM (2.6.0) -- 2023/04/03 + * new feature + + compatible to CSLMNtal + SLIM (2.5.0) -- 2021/04/19 * new feature + add --history-management diff --git a/VERSION b/VERSION index 437459cd..e70b4523 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.5.0 +2.6.0 diff --git a/autogen.sh b/autogen.sh index 6d10a19b..992bf819 100755 --- a/autogen.sh +++ b/autogen.sh @@ -11,7 +11,18 @@ run () fi } +# makeshift +autoheader=autoheader +autoreconf=autoreconf +autoconf --version | grep 2.69 >/dev/null +if test $? != 0 ; then + echo "autoconf 2.69 is not installed." + echo "Trying to use autoconf2.69 instead." + autoheader=autoheader2.69 + autoreconf=autoreconf2.69 +fi + run aclocal -run autoheader +run $autoheader run automake --add-missing -run autoreconf +run $autoreconf diff --git a/configure.ac b/configure.ac index f20c5c23..8b14b23a 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ # $Id: configure.ac,v 1.13 2008/10/05 11:22:41 riki Exp $ AC_PREREQ([2.71]) -AC_INIT([SLIM],[2.5.0],[lmntal@ueda.info.waseda.ac.jp],[slim]) +AC_INIT([SLIM], [2.6.0], [lmntal@ueda.info.waseda.ac.jp], [slim]) # AC_REVISION($Revision: 1.13 $) # AC_COPYRIGHT (copyright-notice) AC_CANONICAL_TARGET diff --git a/src/element/alloc.cpp b/src/element/alloc.cpp index 7fabd551..fa153f49 100644 --- a/src/element/alloc.cpp +++ b/src/element/alloc.cpp @@ -74,6 +74,7 @@ LmnSymbolAtomRef lmn_new_atom(LmnFunctor f) { ap->set_functor(f); ap->set_id(0); + ap->record_flag = false; return ap; } diff --git a/src/element/instruction.cpp b/src/element/instruction.cpp index 2781d120..393c703b 100644 --- a/src/element/instruction.cpp +++ b/src/element/instruction.cpp @@ -247,12 +247,14 @@ const std::map instr_spec = { {INSTR_IDIV, {"idiv", {InstrVar, InstrVar, InstrVar}}}, {INSTR_INEG, {"ineg", {InstrVar, InstrVar}}}, {INSTR_IMOD, {"imod", {InstrVar, InstrVar, InstrVar}}}, + {INSTR_IABS, {"iabs", {InstrVar, InstrVar, InstrVar}}}, {INSTR_ILT, {"ilt", {InstrVar, InstrVar}}}, {INSTR_ILE, {"ile", {InstrVar, InstrVar}}}, {INSTR_IGT, {"igt", {InstrVar, InstrVar}}}, {INSTR_IGE, {"ige", {InstrVar, InstrVar}}}, {INSTR_IEQ, {"ieq", {InstrVar, InstrVar}}}, {INSTR_INE, {"ine", {InstrVar, InstrVar}}}, + {INSTR_INOT, {"inot", {InstrVar, InstrVar, InstrVar}}}, {INSTR_IAND, {"iand", {InstrVar, InstrVar, InstrVar}}}, {INSTR_IOR, {"ior", {InstrVar, InstrVar, InstrVar}}}, {INSTR_IXOR, {"ixor", {InstrVar, InstrVar, InstrVar}}}, @@ -268,6 +270,7 @@ const std::map instr_spec = { {INSTR_IMULFUNC, {"imulfunc", {InstrVar, InstrVar, InstrVar}}}, {INSTR_IDIVFUNC, {"idivfunc", {InstrVar, InstrVar, InstrVar}}}, {INSTR_IMODFUNC, {"imodfunc", {InstrVar, InstrVar, InstrVar}}}, + {INSTR_IABSFUNC, {"iabsfunc", {InstrVar, InstrVar, InstrVar}}}, {INSTR_GETCLASS, {"getclass", {InstrVar, InstrVar}}}, {INSTR_SUBCLASS, {"subclass", {InstrVar, InstrVar}}}, diff --git a/src/element/instruction.hpp b/src/element/instruction.hpp index 33989aff..b40fa19c 100644 --- a/src/element/instruction.hpp +++ b/src/element/instruction.hpp @@ -190,6 +190,7 @@ enum LmnInstruction { INSTR_IDIV, INSTR_INEG, INSTR_IMOD, + INSTR_IABS, INSTR_INOT, INSTR_IAND, INSTR_IOR, @@ -203,6 +204,7 @@ enum LmnInstruction { INSTR_IDIVFUNC, INSTR_INEGFUNC, INSTR_IMODFUNC, + INSTR_IABSFUNC, INSTR_INOTFUNC, INSTR_IANDFUNC, INSTR_IORFUNC, diff --git a/src/loader/il_lexer.cpp.re b/src/loader/il_lexer.cpp.re index ec5c6441..f45ee938 100644 --- a/src/loader/il_lexer.cpp.re +++ b/src/loader/il_lexer.cpp.re @@ -117,7 +117,7 @@ start: exponent = [eE][-+]?integer; blank = [ \t\n\r]; - sstr = "'" [^']* "'"; + sstr = "'" ([^']|"\\'")* "'"; dstr = "\"" ([^"]|"\\\"")* "\""; linecomment = ("//"|"%"|"#") .* [\n]; @@ -127,7 +127,7 @@ start: '-'?digit+ { string s = get_token(); - yylval->as() = s.empty() ? 0 : stol(s); + yylval->as() = s.empty() ? 0 : stol(s); return parser::token::INT; } '-'?integer("."integer)?exponent? { diff --git a/src/loader/il_parser.ypp b/src/loader/il_parser.ypp index bbec2e15..a6ad2073 100644 --- a/src/loader/il_parser.ypp +++ b/src/loader/il_parser.ypp @@ -56,7 +56,7 @@ namespace c17 = slim::element; %lex-param {il::lexer* scanner} %define api.value.type variant -%token INT +%token INT %token FLOAT %token ID SUBRULE_ID %token INST_NAME diff --git a/src/loader/location.hh b/src/loader/location.hh index 345d084e..20d13862 100644 --- a/src/loader/location.hh +++ b/src/loader/location.hh @@ -1,8 +1,8 @@ -// A Bison parser, made by GNU Bison 3.0.4. +// A Bison parser, made by GNU Bison 3.7.3. // Locations for Bison parsers in C++ -// Copyright (C) 2002-2015 Free Software Foundation, Inc. +// Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc. // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -38,44 +38,163 @@ #ifndef YY_IL_LOCATION_HH_INCLUDED # define YY_IL_LOCATION_HH_INCLUDED -# include "position.hh" - +# include +# include + +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) +# endif +# endif namespace il { -#line 46 "location.hh" // location.cc:296 - /// Abstract a location. +#line 58 "location.hh" + + /// A point in a source file. + class position + { + public: + /// Type for file name. + typedef const std::string filename_type; + /// Type for line and column numbers. + typedef int counter_type; + + /// Construct a position. + explicit position (filename_type* f = YY_NULLPTR, + counter_type l = 1, + counter_type c = 1) + : filename (f) + , line (l) + , column (c) + {} + + + /// Initialization. + void initialize (filename_type* fn = YY_NULLPTR, + counter_type l = 1, + counter_type c = 1) + { + filename = fn; + line = l; + column = c; + } + + /** \name Line and Column related manipulators + ** \{ */ + /// (line related) Advance to the COUNT next lines. + void lines (counter_type count = 1) + { + if (count) + { + column = 1; + line = add_ (line, count, 1); + } + } + + /// (column related) Advance to the COUNT next columns. + void columns (counter_type count = 1) + { + column = add_ (column, count, 1); + } + /** \} */ + + /// File name to which this position refers. + filename_type* filename; + /// Current line number. + counter_type line; + /// Current column number. + counter_type column; + + private: + /// Compute max (min, lhs+rhs). + static counter_type add_ (counter_type lhs, counter_type rhs, counter_type min) + { + return lhs + rhs < min ? min : lhs + rhs; + } + }; + + /// Add \a width columns, in place. + inline position& + operator+= (position& res, position::counter_type width) + { + res.columns (width); + return res; + } + + /// Add \a width columns. + inline position + operator+ (position res, position::counter_type width) + { + return res += width; + } + + /// Subtract \a width columns, in place. + inline position& + operator-= (position& res, position::counter_type width) + { + return res += -width; + } + + /// Subtract \a width columns. + inline position + operator- (position res, position::counter_type width) + { + return res -= width; + } + + /** \brief Intercept output stream redirection. + ** \param ostr the destination output stream + ** \param pos a reference to the position to redirect + */ + template + std::basic_ostream& + operator<< (std::basic_ostream& ostr, const position& pos) + { + if (pos.filename) + ostr << *pos.filename << ':'; + return ostr << pos.line << '.' << pos.column; + } + + /// Two points in a source file. class location { public: + /// Type for file name. + typedef position::filename_type filename_type; + /// Type for line and column numbers. + typedef position::counter_type counter_type; /// Construct a location from \a b to \a e. location (const position& b, const position& e) : begin (b) , end (e) - { - } + {} /// Construct a 0-width location in \a p. explicit location (const position& p = position ()) : begin (p) , end (p) - { - } + {} /// Construct a 0-width location in \a f, \a l, \a c. - explicit location (std::string* f, - unsigned int l = 1u, - unsigned int c = 1u) + explicit location (filename_type* f, + counter_type l = 1, + counter_type c = 1) : begin (f, l, c) , end (f, l, c) - { - } + {} /// Initialization. - void initialize (std::string* f = YY_NULLPTR, - unsigned int l = 1u, - unsigned int c = 1u) + void initialize (filename_type* f = YY_NULLPTR, + counter_type l = 1, + counter_type c = 1) { begin.initialize (f, l, c); end = begin; @@ -91,13 +210,13 @@ namespace il { } /// Extend the current location to the COUNT next columns. - void columns (int count = 1) + void columns (counter_type count = 1) { end += count; } /// Extend the current location to the COUNT next lines. - void lines (int count = 1) + void lines (counter_type count = 1) { end.lines (count); } @@ -112,57 +231,49 @@ namespace il { }; /// Join two locations, in place. - inline location& operator+= (location& res, const location& end) + inline location& + operator+= (location& res, const location& end) { res.end = end.end; return res; } /// Join two locations. - inline location operator+ (location res, const location& end) + inline location + operator+ (location res, const location& end) { return res += end; } /// Add \a width columns to the end position, in place. - inline location& operator+= (location& res, int width) + inline location& + operator+= (location& res, location::counter_type width) { res.columns (width); return res; } /// Add \a width columns to the end position. - inline location operator+ (location res, int width) + inline location + operator+ (location res, location::counter_type width) { return res += width; } /// Subtract \a width columns to the end position, in place. - inline location& operator-= (location& res, int width) + inline location& + operator-= (location& res, location::counter_type width) { return res += -width; } /// Subtract \a width columns to the end position. - inline location operator- (location res, int width) + inline location + operator- (location res, location::counter_type width) { return res -= width; } - /// Compare two location objects. - inline bool - operator== (const location& loc1, const location& loc2) - { - return loc1.begin == loc2.begin && loc1.end == loc2.end; - } - - /// Compare two location objects. - inline bool - operator!= (const location& loc1, const location& loc2) - { - return !(loc1 == loc2); - } - /** \brief Intercept output stream redirection. ** \param ostr the destination output stream ** \param loc a reference to the location to redirect @@ -170,10 +281,11 @@ namespace il { ** Avoid duplicate information. */ template - inline std::basic_ostream& + std::basic_ostream& operator<< (std::basic_ostream& ostr, const location& loc) { - unsigned int end_col = 0 < loc.end.column ? loc.end.column - 1 : 0; + location::counter_type end_col + = 0 < loc.end.column ? loc.end.column - 1 : 0; ostr << loc.begin; if (loc.end.filename && (!loc.begin.filename @@ -186,7 +298,7 @@ namespace il { return ostr; } - } // il -#line 192 "location.hh" // location.cc:296 +#line 303 "location.hh" + #endif // !YY_IL_LOCATION_HH_INCLUDED diff --git a/src/loader/position.hh b/src/loader/position.hh index 1bf1f7af..3494f255 100644 --- a/src/loader/position.hh +++ b/src/loader/position.hh @@ -1,180 +1,11 @@ -// A Bison parser, made by GNU Bison 3.0.4. +// A Bison parser, made by GNU Bison 3.7.3. -// Positions for Bison parsers in C++ +// Starting with Bison 3.2, this file is useless: the structure it +// used to define is now defined in "location.hh". +// +// To get rid of this file: +// 1. add '%require "3.2"' (or newer) to your grammar file +// 2. remove references to this file from your build system +// 3. if you used to include it, include "location.hh" instead. -// Copyright (C) 2002-2015 Free Software Foundation, Inc. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// As a special exception, you may create a larger work that contains -// part or all of the Bison parser skeleton and distribute that work -// under terms of your choice, so long as that work isn't itself a -// parser generator using the skeleton or a modified version thereof -// as a parser skeleton. Alternatively, if you modify or redistribute -// the parser skeleton itself, you may (at your option) remove this -// special exception, which will cause the skeleton and the resulting -// Bison output files to be licensed under the GNU General Public -// License without this special exception. - -// This special exception was added by the Free Software Foundation in -// version 2.2 of Bison. - -/** - ** \file position.hh - ** Define the il::position class. - */ - -#ifndef YY_IL_POSITION_HH_INCLUDED -# define YY_IL_POSITION_HH_INCLUDED - -# include // std::max -# include -# include - -# ifndef YY_NULLPTR -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULLPTR nullptr -# else -# define YY_NULLPTR 0 -# endif -# endif - - -namespace il { -#line 56 "position.hh" // location.cc:296 - /// Abstract a position. - class position - { - public: - /// Construct a position. - explicit position (std::string* f = YY_NULLPTR, - unsigned int l = 1u, - unsigned int c = 1u) - : filename (f) - , line (l) - , column (c) - { - } - - - /// Initialization. - void initialize (std::string* fn = YY_NULLPTR, - unsigned int l = 1u, - unsigned int c = 1u) - { - filename = fn; - line = l; - column = c; - } - - /** \name Line and Column related manipulators - ** \{ */ - /// (line related) Advance to the COUNT next lines. - void lines (int count = 1) - { - if (count) - { - column = 1u; - line = add_ (line, count, 1); - } - } - - /// (column related) Advance to the COUNT next columns. - void columns (int count = 1) - { - column = add_ (column, count, 1); - } - /** \} */ - - /// File name to which this position refers. - std::string* filename; - /// Current line number. - unsigned int line; - /// Current column number. - unsigned int column; - - private: - /// Compute max(min, lhs+rhs) (provided min <= lhs). - static unsigned int add_ (unsigned int lhs, int rhs, unsigned int min) - { - return (0 < rhs || -static_cast(rhs) < lhs - ? rhs + lhs - : min); - } - }; - - /// Add \a width columns, in place. - inline position& - operator+= (position& res, int width) - { - res.columns (width); - return res; - } - - /// Add \a width columns. - inline position - operator+ (position res, int width) - { - return res += width; - } - - /// Subtract \a width columns, in place. - inline position& - operator-= (position& res, int width) - { - return res += -width; - } - - /// Subtract \a width columns. - inline position - operator- (position res, int width) - { - return res -= width; - } - - /// Compare two position objects. - inline bool - operator== (const position& pos1, const position& pos2) - { - return (pos1.line == pos2.line - && pos1.column == pos2.column - && (pos1.filename == pos2.filename - || (pos1.filename && pos2.filename - && *pos1.filename == *pos2.filename))); - } - - /// Compare two position objects. - inline bool - operator!= (const position& pos1, const position& pos2) - { - return !(pos1 == pos2); - } - - /** \brief Intercept output stream redirection. - ** \param ostr the destination output stream - ** \param pos a reference to the position to redirect - */ - template - inline std::basic_ostream& - operator<< (std::basic_ostream& ostr, const position& pos) - { - if (pos.filename) - ostr << *pos.filename << ':'; - return ostr << pos.line << '.' << pos.column; - } - - -} // il -#line 180 "position.hh" // location.cc:296 -#endif // !YY_IL_POSITION_HH_INCLUDED +#include "location.hh" diff --git a/src/loader/stack.hh b/src/loader/stack.hh index 05838a15..36dff2d8 100644 --- a/src/loader/stack.hh +++ b/src/loader/stack.hh @@ -1,157 +1,8 @@ -// A Bison parser, made by GNU Bison 3.0.4. - -// Stack handling for Bison parsers in C++ - -// Copyright (C) 2002-2015 Free Software Foundation, Inc. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// As a special exception, you may create a larger work that contains -// part or all of the Bison parser skeleton and distribute that work -// under terms of your choice, so long as that work isn't itself a -// parser generator using the skeleton or a modified version thereof -// as a parser skeleton. Alternatively, if you modify or redistribute -// the parser skeleton itself, you may (at your option) remove this -// special exception, which will cause the skeleton and the resulting -// Bison output files to be licensed under the GNU General Public -// License without this special exception. - -// This special exception was added by the Free Software Foundation in -// version 2.2 of Bison. - -/** - ** \file stack.hh - ** Define the il::stack class. - */ - -#ifndef YY_IL_STACK_HH_INCLUDED -# define YY_IL_STACK_HH_INCLUDED - -# include - - -namespace il { -#line 46 "stack.hh" // stack.hh:132 - template > - class stack - { - public: - // Hide our reversed order. - typedef typename S::reverse_iterator iterator; - typedef typename S::const_reverse_iterator const_iterator; - - stack () - : seq_ () - { - seq_.reserve (200); - } - - stack (unsigned int n) - : seq_ (n) - {} - - inline - T& - operator[] (unsigned int i) - { - return seq_[seq_.size () - 1 - i]; - } - - inline - const T& - operator[] (unsigned int i) const - { - return seq_[seq_.size () - 1 - i]; - } - - /// Steal the contents of \a t. - /// - /// Close to move-semantics. - inline - void - push (T& t) - { - seq_.push_back (T()); - operator[](0).move (t); - } - - inline - void - pop (unsigned int n = 1) - { - for (; n; --n) - seq_.pop_back (); - } - - void - clear () - { - seq_.clear (); - } - - inline - typename S::size_type - size () const - { - return seq_.size (); - } - - inline - const_iterator - begin () const - { - return seq_.rbegin (); - } - - inline - const_iterator - end () const - { - return seq_.rend (); - } - - private: - stack (const stack&); - stack& operator= (const stack&); - /// The wrapped container. - S seq_; - }; - - /// Present a slice of the top of a stack. - template > - class slice - { - public: - slice (const S& stack, unsigned int range) - : stack_ (stack) - , range_ (range) - {} - - inline - const T& - operator [] (unsigned int i) const - { - return stack_[range_ - i]; - } - - private: - const S& stack_; - unsigned int range_; - }; - - -} // il -#line 156 "stack.hh" // stack.hh:132 - -#endif // !YY_IL_STACK_HH_INCLUDED +// A Bison parser, made by GNU Bison 3.7.3. + +// Starting with Bison 3.2, this file is useless: the structure it +// used to define is now defined with the parser itself. +// +// To get rid of this file: +// 1. add '%require "3.2"' (or newer) to your grammar file +// 2. remove references to this file from your build system. diff --git a/src/verifier/mc.cpp b/src/verifier/mc.cpp index e0ea8f7a..8d05cbe8 100644 --- a/src/verifier/mc.cpp +++ b/src/verifier/mc.cpp @@ -113,7 +113,7 @@ static inline void do_mc(LmnMembraneRef world_mem_org, AutomataRef a, wp = new LmnWorkerGroup(a, psyms, thread_num); states = worker_states(wp->get_worker(LMN_PRIMARY_ID)); p_label = a ? a->get_init_state() : DEFAULT_STATE_ID; - mem = world_mem_org->copy(); + mem = world_mem_org->copy_ex(); init_s = new State(mem, p_label, states->use_memenc()); state_id_issue(init_s); /* 状態に整数IDを発行 */ #ifdef KWBT_OPT diff --git a/src/vm/dumper.cpp b/src/vm/dumper.cpp index 7eb99469..d3cca573 100644 --- a/src/vm/dumper.cpp +++ b/src/vm/dumper.cpp @@ -235,7 +235,7 @@ static BOOL dump_data_atom(LmnPortRef port, LmnAtomRef data, LmnLinkAttr attr) { break; case LMN_HL_ATTR: { char buf[18]; - port_put_raw_s(port, EXCLAMATION_NAME); + port_put_raw_s(port, "!");// port_put_raw_s(port, HYPERLINK_NAME); if (lmn_env.show_hyperlink) { // sprintf(buf, "H%lx", sprintf(buf, "H%lu", diff --git a/src/vm/functor.cpp b/src/vm/functor.cpp index da46ba20..0cd1abc5 100644 --- a/src/vm/functor.cpp +++ b/src/vm/functor.cpp @@ -75,7 +75,7 @@ struct PredefinedFunctor predefined_functors[] = { {LMN_FALSE_FUNCTOR, FALSE, FALSE_ATOM_NAME, 1}, /* hyperlinkは第二引数にHyperLink構造体へのポインタを埋め込むため二引数として登録する */ - {LMN_EXCLAMATION_FUNCTOR, FALSE, EXCLAMATION_NAME, 2}, + {LMN_EXCLAMATION_FUNCTOR, FALSE, HYPERLINK_NAME, 2}, #ifdef USE_FIRSTCLASS_RULE {LMN_COLON_MINUS_FUNCTOR, FALSE, COLON_MINUS_ATOM_NAME, 3}, #endif diff --git a/src/vm/functor.h b/src/vm/functor.h index e29cbfc7..8d3634bb 100644 --- a/src/vm/functor.h +++ b/src/vm/functor.h @@ -125,7 +125,7 @@ extern LmnFunctorTable *lmn_functor_table; #define MEM_EQ_ATOM_NAME "mem_eq" #define TRUE_ATOM_NAME "true" #define FALSE_ATOM_NAME "false" -#define EXCLAMATION_NAME "!" +#define HYPERLINK_NAME "!jRmVnNw.8xo[muc#qX" //通常atom名として使用されないようなランダム文字列 #define LMN_IN_PROXY_FUNCTOR 0 #define LMN_OUT_PROXY_FUNCTOR 1 diff --git a/src/vm/task.cpp b/src/vm/task.cpp index 3e27b2f5..64090a98 100644 --- a/src/vm/task.cpp +++ b/src/vm/task.cpp @@ -1059,6 +1059,35 @@ struct exec_subinstructions_branch { } }; +static bool push_updated_hl_cmems +( LmnMembraneRef mem, + std::vector &buf, int id ) +{ + bool is_updated = false; + for (auto *cmem = mem->child_head; cmem; cmem = cmem->next) { + /* 子膜側に再帰 */ + bool updated_hl = push_updated_hl_cmems( cmem, buf, id ); + + /* 現在の膜の検査. 子膜側に変化があったら冗長のためskip */ + auto *ent = cmem->get_atomlist( LMN_HL_FUNC ); + if (!updated_hl) { + LmnSymbolAtomRef atom; + EACH_ATOM( atom, ent, { + auto hl_id = LMN_HL_ID( LMN_HL_ATOM_ROOT_HL( atom ) ); + updated_hl = (hl_id == id); + if (updated_hl) break; + }); + } + + /* 変化があった場合, 当該膜をメモしておく */ + if (updated_hl) { + buf.push_back( cmem ); + is_updated = true; + } + } + return is_updated; +} + /** * execute a command at instr. * instr is incremented by the size of operation. @@ -2796,7 +2825,7 @@ bool slim::vm::interpreter::exec_command(LmnReactCxt *rc, LmnRuleRef rule, } case LMN_HL_ATTR: { char buf[16]; - port_put_raw_s(port, EXCLAMATION_NAME); + port_put_raw_s(port, HYPERLINK_NAME); sprintf(buf, "%lx", LMN_HL_ID(LMN_HL_ATOM_ROOT_HL( (LmnSymbolAtomRef)rc->wt(srcvec->get(0))))); @@ -2967,6 +2996,14 @@ bool slim::vm::interpreter::exec_command(LmnReactCxt *rc, LmnRuleRef rule, lmn_mem_delete_atom(m, (LmnAtomRef)rc->wt(atomi), rc->at(atomi)); lmn_mem_delete_atom(m, atom1, (LmnWord)attr1); lmn_mem_delete_atom(m, atom2, (LmnWord)attr2); + + if (rc->has_mode(REACT_MEM_ORIENTED) && hl1 && hl1->get_root()) { + std::vector mbuf;/* memstackの逆順 */ + push_updated_hl_cmems( m, mbuf, LMN_HL_ID( hl1->get_root() ) ); + /* stackの逆順に親子関係が並んでいるので, 逆順にstackへ積む */ + for (int i = (int)mbuf.size()-1; i >= 0; i--) + ((MemReactContext *)rc)->memstack_push( mbuf[i] ); + } } break; } @@ -3505,8 +3542,8 @@ bool slim::vm::interpreter::exec_command(LmnReactCxt *rc, LmnRuleRef rule, READ_VAL(LmnInstrVar, instr, atom1); READ_VAL(LmnInstrVar, instr, atom2); rc->reg(dstatom) = { - static_cast(((long)rc->wt(atom1) + (long)rc->wt(atom2))), - LMN_INT_ATTR, TT_ATOM}; + static_cast(((long)rc->wt(atom1) + (long)rc->wt(atom2))), + LMN_INT_ATTR, TT_ATOM}; break; } case INSTR_ISUB: { @@ -3514,10 +3551,9 @@ bool slim::vm::interpreter::exec_command(LmnReactCxt *rc, LmnRuleRef rule, READ_VAL(LmnInstrVar, instr, dstatom); READ_VAL(LmnInstrVar, instr, atom1); READ_VAL(LmnInstrVar, instr, atom2); - rc->reg(dstatom) = { - static_cast(((long)rc->wt(atom1) - (long)rc->wt(atom2))), - LMN_INT_ATTR, TT_ATOM}; + static_cast(((long)rc->wt(atom1) - (long)rc->wt(atom2))), + LMN_INT_ATTR, TT_ATOM}; break; } case INSTR_IMUL: { @@ -3525,10 +3561,9 @@ bool slim::vm::interpreter::exec_command(LmnReactCxt *rc, LmnRuleRef rule, READ_VAL(LmnInstrVar, instr, dstatom); READ_VAL(LmnInstrVar, instr, atom1); READ_VAL(LmnInstrVar, instr, atom2); - rc->reg(dstatom) = { - static_cast(((long)rc->wt(atom1) * (long)rc->wt(atom2))), - LMN_INT_ATTR, TT_ATOM}; + static_cast(((long)rc->wt(atom1) * (long)rc->wt(atom2))), + LMN_INT_ATTR, TT_ATOM}; break; } case INSTR_IDIV: { @@ -3536,19 +3571,18 @@ bool slim::vm::interpreter::exec_command(LmnReactCxt *rc, LmnRuleRef rule, READ_VAL(LmnInstrVar, instr, dstatom); READ_VAL(LmnInstrVar, instr, atom1); READ_VAL(LmnInstrVar, instr, atom2); - rc->reg(dstatom) = { - static_cast(((long)rc->wt(atom1) / (long)rc->wt(atom2))), - LMN_INT_ATTR, TT_ATOM}; - + static_cast(((long)rc->wt(atom1) / (long)rc->wt(atom2))), + LMN_INT_ATTR, TT_ATOM};; break; } case INSTR_INEG: { LmnInstrVar dstatom, atomi; READ_VAL(LmnInstrVar, instr, dstatom); READ_VAL(LmnInstrVar, instr, atomi); - rc->reg(dstatom) = {static_cast((-(long)rc->wt(atomi))), - LMN_INT_ATTR, TT_ATOM}; + rc->reg(dstatom) = { + static_cast((-(long)rc->wt(atomi))), + LMN_INT_ATTR, TT_ATOM}; break; } case INSTR_IMOD: { @@ -3556,29 +3590,37 @@ bool slim::vm::interpreter::exec_command(LmnReactCxt *rc, LmnRuleRef rule, READ_VAL(LmnInstrVar, instr, dstatom); READ_VAL(LmnInstrVar, instr, atom1); READ_VAL(LmnInstrVar, instr, atom2); - rc->reg(dstatom) = { - static_cast(((long)rc->wt(atom1) % (long)rc->wt(atom2))), - LMN_INT_ATTR, TT_ATOM}; - break; - } - // case INSTR_INOT: { - // LmnInstrVar dstatom, atomi; - // READ_VAL(LmnInstrVar, instr, dstatom); - // READ_VAL(LmnInstrVar, instr, atomi); - // rc->reg(dstatom) = {static_cast((~(int)rc->wt(atomi))), - // LMN_INT_ATTR, TT_ATOM}; - // break; - // } + static_cast(((long)rc->wt(atom1) % (long)rc->wt(atom2))), + LMN_INT_ATTR, TT_ATOM}; + break; + } + case INSTR_IABS: { + LmnInstrVar dstatom, atomi; + READ_VAL(LmnInstrVar, instr, dstatom); + READ_VAL(LmnInstrVar, instr, atomi); + rc->reg(dstatom) = { + static_cast(abs((long)rc->wt(atomi))), + LMN_INT_ATTR, TT_ATOM}; + break; + } + case INSTR_INOT: { + LmnInstrVar dstatom, atomi; + READ_VAL(LmnInstrVar, instr, dstatom); + READ_VAL(LmnInstrVar, instr, atomi); + rc->reg(dstatom) = { + static_cast((~(long)rc->wt(atomi))), + LMN_INT_ATTR, TT_ATOM}; + break; + } case INSTR_IAND: { LmnInstrVar dstatom, atom1, atom2; READ_VAL(LmnInstrVar, instr, dstatom); READ_VAL(LmnInstrVar, instr, atom1); READ_VAL(LmnInstrVar, instr, atom2); - rc->reg(dstatom) = { - static_cast(((long)rc->wt(atom1) & (long)rc->wt(atom2))), - LMN_INT_ATTR, TT_ATOM}; + static_cast(((long)rc->wt(atom1) & (long)rc->wt(atom2))), + LMN_INT_ATTR, TT_ATOM}; break; } case INSTR_IOR: { @@ -3586,11 +3628,9 @@ bool slim::vm::interpreter::exec_command(LmnReactCxt *rc, LmnRuleRef rule, READ_VAL(LmnInstrVar, instr, dstatom); READ_VAL(LmnInstrVar, instr, atom1); READ_VAL(LmnInstrVar, instr, atom2); - rc->reg(dstatom) = { - static_cast(((long)rc->wt(atom1) | (long)rc->wt(atom2))), - LMN_INT_ATTR, TT_ATOM}; - + static_cast(((long)rc->wt(atom1) | (long)rc->wt(atom2))), + LMN_INT_ATTR, TT_ATOM}; break; } case INSTR_IXOR: { @@ -3598,10 +3638,9 @@ bool slim::vm::interpreter::exec_command(LmnReactCxt *rc, LmnRuleRef rule, READ_VAL(LmnInstrVar, instr, dstatom); READ_VAL(LmnInstrVar, instr, atom1); READ_VAL(LmnInstrVar, instr, atom2); - rc->reg(dstatom) = { - static_cast(((long)rc->wt(atom1) ^ (long)rc->wt(atom2))), - LMN_INT_ATTR, TT_ATOM}; + static_cast(((long)rc->wt(atom1) ^ (long)rc->wt(atom2))), + LMN_INT_ATTR, TT_ATOM}; break; } case INSTR_ISAL: { @@ -3614,8 +3653,8 @@ bool slim::vm::interpreter::exec_command(LmnReactCxt *rc, LmnRuleRef rule, long tmp1 = (long)rc->wt(atom1); long tmp2 = (long)rc->wt(atom2); rc->reg(dstatom) = { - static_cast((tmp2 >= 0) ? tmp1 << tmp2 : tmp1 >> -tmp2), - LMN_INT_ATTR, TT_ATOM}; + static_cast((tmp2 >= 0) ? tmp1 << tmp2 : tmp1 >> -tmp2), + LMN_INT_ATTR, TT_ATOM}; break; } case INSTR_ILT: { diff --git a/test/README.md b/test/README.md index b276de4b..50ea2bbe 100644 --- a/test/README.md +++ b/test/README.md @@ -87,16 +87,18 @@ Automake の TAP を用いて,自動的にテストを行います. ```bash #!/bin/sh ./check.pl \ - /testsuite/basic/append1 \ - /testsuite/basic/append2 \ - /testsuite/basic/append3 \ - /testsuite/basic/append4 + /testsuite/append/append1 \ + /testsuite/append/append2 \ + /testsuite/append/append3 \ + /testsuite/append/append4 ``` - `check.sh` ファイルでは, [`./check.pl`](system_check/check.pl) を呼び出し, その引数として, - テストしたい `.lmntest` ファイルのパスから `.lmntest` を除いたもの - (e.g., `/testsuite/basic/append1`) + テストしたい `.lmntest` ファイルのパス + (e.g., `/testsuite/append/append1.lmntest`) + から `.lmntest` を除いたもの + (e.g., `/testsuite/append/append1`) を全て与えてください. 2. [system_check/Makefile.am](system_check/Makefile.am) の 1. `TESTS` 変数に, @@ -108,6 +110,35 @@ Automake の TAP を用いて,自動的にテストを行います. を追加してください. - E.g., `check_DATA = testsuite//.lmntest` +### オプションの指定 + +Compiler option は `/Makefile.am` で, +`LMNCFLAGS` で指定している. + +- E.g., [system_check/Makefile.am](system_check/Makefile.am) + + ```bash + LMNCFLAGS = --hl-opt --slimcode -O3 + ``` + +Runtime option は, +`/check.pl` で, +`slim_CHECK_OPTIONS` 環境変数を読み込んで指定している. + +- E.g., [system_check/check.pl](system_check/check.pl) + + ```perl + $options = $ENV{slim_CHECK_OPTIONS}; + ``` + +- 例えば,`--history-management` を用いながらテストしたい場合は, + + ```bash + export slim_CHECK_OPTIONS="--history-management" + ``` + + してから `make check` する. + ## Directory Structure [system_check](system_check)/testsuite