Changeset f53acdf8


Ignore:
Timestamp:
Jul 19, 2019, 2:16:01 PM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
arm-eh, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
4eb43fa
Parents:
1f1c102 (diff), 8ac3b0e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into new-ast

Files:
9 added
3 deleted
95 edited

Legend:

Unmodified
Added
Removed
  • Jenkinsfile_disabled

    r1f1c102 rf53acdf8  
    22
    33import groovy.transform.Field
     4
     5// For skipping stages
     6import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
    47
    58//===========================================================================================================
     
    8285//===========================================================================================================
    8386def clean() {
    84         build_stage('Cleanup') {
     87        build_stage('Cleanup', true) {
    8588                // clean the build by wipping the build directory
    8689                dir(BuildDir) {
     
    9295//Compilation script is done here but environnement set-up and error handling is done in main loop
    9396def checkout() {
    94         build_stage('Checkout') {
     97        build_stage('Checkout', true) {
    9598                //checkout the source code and clean the repo
    9699                final scmVars = checkout scm
     
    103106
    104107def build() {
    105         build_stage('Build') {
     108        // build_stage('Build', true) {
     109        //      // Build outside of the src tree to ease cleaning
     110        //      dir (BuildDir) {
     111        //              //Configure the conpilation (Output is not relevant)
     112        //              //Use the current directory as the installation target so nothing escapes the sandbox
     113        //              //Also specify the compiler by hand
     114        //              targets=""
     115        //              if( Settings.RunAllTests || Settings.RunBenchmark ) {
     116        //                      targets="--with-target-hosts='host:debug,host:nodebug'"
     117        //              } else {
     118        //                      targets="--with-target-hosts='host:debug'"
     119        //              }
     120
     121        //              sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --quiet"
     122
     123        //              //Compile the project
     124        //              sh 'make -j 8 --no-print-directory'
     125        //      }
     126        // }
     127
     128        debug = true
     129        release = Settings.RunAllTests || Settings.RunBenchmark
     130        build_stage('Build : configure', true) {
    106131                // Build outside of the src tree to ease cleaning
    107132                dir (BuildDir) {
     
    118143                        sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --quiet"
    119144
    120                         //Compile the project
    121                         sh 'make -j 8 --no-print-directory'
     145                        // Configure libcfa
     146                        sh 'make -j 8 --no-print-directory configure-libcfa'
     147                }
     148        }
     149
     150        build_stage('Build : cfa-cpp', true) {
     151                // Build outside of the src tree to ease cleaning
     152                dir (BuildDir) {
     153                        // Build driver
     154                        sh 'make -j 8 --no-print-directory -C driver'
     155
     156                        // Build translator
     157                        sh 'make -j 8 --no-print-directory -C src'
     158                }
     159        }
     160
     161        build_stage('Build : libcfa(debug)', debug) {
     162                // Build outside of the src tree to ease cleaning
     163                dir (BuildDir) {
     164                        sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-debug"
     165                }
     166        }
     167
     168        build_stage('Build : libcfa(nodebug)', release) {
     169                // Build outside of the src tree to ease cleaning
     170                dir (BuildDir) {
     171                        sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-nodebug"
    122172                }
    123173        }
     
    125175
    126176def test() {
    127         build_stage('Test') {
    128 
     177        build_stage('Test: short', !Settings.RunAllTests) {
    129178                dir (BuildDir) {
    130179                        //Run the tests from the tests directory
    131                         if ( Settings.RunAllTests ) {
    132                                 sh 'make --no-print-directory -C tests timeouts="--timeout=1200" all-tests debug=yes'
    133                                 sh 'make --no-print-directory -C tests timeouts="--timeout=1200" all-tests debug=no '
    134                         }
    135                         else {
    136                                 sh 'make --no-print-directory -C tests'
    137                         }
     180                        sh 'make --no-print-directory -C tests'
     181                }
     182        }
     183
     184        build_stage('Test: full', Settings.RunAllTests) {
     185                dir (BuildDir) {
     186                        //Run the tests from the tests directory
     187                        sh 'make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes'
     188                        sh 'make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no '
    138189                }
    139190        }
     
    141192
    142193def benchmark() {
    143         build_stage('Benchmark') {
    144 
    145                 if( !Settings.RunBenchmark ) return
    146 
     194        build_stage('Benchmark', Settings.RunBenchmark) {
    147195                dir (BuildDir) {
    148196                        //Append bench results
     
    153201
    154202def build_doc() {
    155         build_stage('Documentation') {
    156 
    157                 if( !Settings.BuildDocumentation ) return
    158 
     203        build_stage('Documentation', Settings.BuildDocumentation) {
    159204                dir ('doc/user') {
    160205                        make_doc()
     
    168213
    169214def publish() {
    170         build_stage('Publish') {
     215        build_stage('Publish', true) {
    171216
    172217                if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
     
    412457}
    413458
    414 def build_stage(String name, Closure block ) {
     459def build_stage(String name, boolean run, Closure block ) {
    415460        StageName = name
    416461        echo " -------- ${StageName} -------- "
    417         stage(name, block)
     462        if(run) {
     463                stage(name, block)
     464        } else {
     465                stage(name) { Utils.markStageSkippedForConditional(STAGE_NAME) }
     466        }
    418467}
    419468
  • Makefile.am

    r1f1c102 rf53acdf8  
    4040        $(MAKE) -C tests all-tests installed=yes debug=${debug}
    4141
     42configure-libcfa: @LIBCFA_TARGET_MAKEFILES@
     43        @true
     44
    4245status: @LIBCFA_TARGET_MAKEFILES@
    4346        @echo -ne "translator\n\t"
  • Makefile.in

    r1f1c102 rf53acdf8  
    940940        $(MAKE) -C tests all-tests installed=yes debug=${debug}
    941941
     942configure-libcfa: @LIBCFA_TARGET_MAKEFILES@
     943        @true
     944
    942945status: @LIBCFA_TARGET_MAKEFILES@
    943946        @echo -ne "translator\n\t"
  • benchmark/Makefile.am

    r1f1c102 rf53acdf8  
    1111## Created On       : Sun May 31 09:08:15 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Sun Jun 23 12:34:29 2019
    14 ## Update Count     : 52
     13## Last Modified On : Mon Jun 24 16:45:42 2019
     14## Update Count     : 53
    1515###############################################################################
    1616
     
    3131BENCH_V_JAVAC = $(__bench_v_JAVAC_$(__quiet))
    3232BENCH_V_UPP = $(__bench_v_UPP_$(__quiet))
    33 BENCH_V_QTHREAD = $(__bench_v_QTHREAD_$(__quiet))
    3433
    3534__quiet = verbose
     
    4645__bench_v_JAVAC_verbose = $(AM_V_JAVAC)
    4746__bench_v_UPP_verbose = $(AM_V_UPP)
    48 __bench_v_QTHREAD_verbose = $(AM_V_CC)
    4947
    5048
     
    176174        ctxswitch-upp_thread.run        \
    177175        ctxswitch-goroutine.run         \
    178         ctxswitch-java_thread.run       \
    179         ctxswitch-qthreads.run
     176        ctxswitch-java_thread.run
    180177
    181178
     
    224221        @echo "java JavaThread" >> a.out
    225222        @chmod a+x a.out
    226 
    227 ctxswitch-qthreads$(EXEEXT):
    228         $(BENCH_V_QTHREADS)$(COMPILE) -DBENCH_N=50000000 -I/u/pabuhr/software/qthreads/include -L/u/pabuhr/software/qthreads/lib -Xlinker -R/u/pabuhr/software/qthreads/lib $(srcdir)/ctxswitch/qthreads.c -lqthread
    229223
    230224## =========================================================================================================
     
    320314        creation-upp_thread.run                 \
    321315        creation-goroutine.run                  \
    322         creation-java_thread.run                \
    323         creation-qthreads.run
     316        creation-java_thread.run
    324317
    325318creation-cfa_coroutine$(EXEEXT):
     
    349342        @echo "java JavaThread" >> a.out
    350343        @chmod a+x a.out
    351 
    352 creation-qthreads$(EXEEXT):
    353         $(BENCH_V_QTHREADS)$(COMPILE) -DBENCH_N=50000000 -I/u/pabuhr/software/qthreads/include -L/u/pabuhr/software/qthreads/lib -Xlinker -R/u/pabuhr/software/qthreads/lib $(srcdir)/ctxswitch/qthreads.c -lqthread
    354344
    355345## =========================================================================================================
  • doc/bibliography/pl.bib

    r1f1c102 rf53acdf8  
    954954    key         = {Cforall Benchmarks},
    955955    author      = {{\textsf{C}{$\mathbf{\forall}$} Benchmarks}},
    956     howpublished= {\href{https://plg.uwaterloo.ca/~cforall/benchmarks}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-benchmarks}},
     956    howpublished= {\href{https://plg.uwaterloo.ca/~cforall/benchmark.tar}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-benchmark.tar}},
    957957}
    958958
  • doc/papers/concurrency/Paper.tex

    r1f1c102 rf53acdf8  
    22
    33\articletype{RESEARCH ARTICLE}%
     4
     5% Referees
     6% Doug Lea, dl@cs.oswego.edu, SUNY Oswego
     7% Herb Sutter, hsutter@microsoft.com, Microsoft Corp
     8% Gor Nishanov, gorn@microsoft.com, Microsoft Corp
     9% James Noble, kjx@ecs.vuw.ac.nz, Victoria University of Wellington, School of Engineering and Computer Science
    410
    511\received{XXXXX}
     
    312318As a result, languages like Java, Scala, Objective-C~\cite{obj-c-book}, \CCeleven~\cite{C11}, and C\#~\cite{Csharp} adopt the 1:1 kernel-threading model, with a variety of presentation mechanisms.
    313319From 2000 onwards, languages like Go~\cite{Go}, Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, D~\cite{D}, and \uC~\cite{uC++,uC++book} have championed the M:N user-threading model, and many user-threading libraries have appeared~\cite{Qthreads,MPC,Marcel}, including putting green threads back into Java~\cite{Quasar}.
    314 The main argument for user-level threading is that they are lighter weight than kernel threads (locking and context switching do not cross the kernel boundary), so there is less restriction on programming styles that encourage large numbers of threads performing medium work units to facilitate load balancing by the runtime~\cite{Verch12}.
     320The main argument for user-level threading is that it is lighter weight than kernel threading (locking and context switching do not cross the kernel boundary), so there is less restriction on programming styles that encourage large numbers of threads performing medium work units to facilitate load balancing by the runtime~\cite{Verch12}.
    315321As well, user-threading facilitates a simpler concurrency approach using thread objects that leverage sequential patterns versus events with call-backs~\cite{Adya02,vonBehren03}.
    316322Finally, performant user-threading implementations (both time and space) meet or exceed direct kernel-threading implementations, while achieving the programming advantages of high concurrency levels and safety.
    317323
    318 A further effort over the past two decades is the development of language memory models to deal with the conflict between language features and compiler/hardware optimizations, \ie, some language features are unsafe in the presence of aggressive sequential optimizations~\cite{Buhr95a,Boehm05}.
     324A further effort over the past two decades is the development of language memory models to deal with the conflict between language features and compiler/hardware optimizations, \ie some language features are unsafe in the presence of aggressive sequential optimizations~\cite{Buhr95a,Boehm05}.
    319325The consequence is that a language must provide sufficient tools to program around safety issues, as inline and library code is all sequential to the compiler.
    320 One solution is low-level qualifiers and functions (\eg, @volatile@ and atomics) allowing \emph{programmers} to explicitly write safe (race-free~\cite{Boehm12}) programs.
     326One solution is low-level qualifiers and functions (\eg @volatile@ and atomics) allowing \emph{programmers} to explicitly write safe (race-free~\cite{Boehm12}) programs.
    321327A safer solution is high-level language constructs so the \emph{compiler} knows the optimization boundaries, and hence, provides implicit safety.
    322328This problem is best known with respect to concurrency, but applies to other complex control-flow, like exceptions\footnote{
     
    324330The key feature that dovetails with this paper is nonlocal exceptions allowing exceptions to be raised across stacks, with synchronous exceptions raised among coroutines and asynchronous exceptions raised among threads, similar to that in \uC~\cite[\S~5]{uC++}
    325331} and coroutines.
    326 Finally, language solutions allow matching constructs with language paradigm, \ie, imperative and functional languages often have different presentations of the same concept to fit their programming model.
     332Finally, language solutions allow matching constructs with language paradigm, \ie imperative and functional languages often have different presentations of the same concept to fit their programming model.
    327333
    328334Finally, it is important for a language to provide safety over performance \emph{as the default}, allowing careful reduction of safety for performance when necessary.
    329 Two concurrency violations of this philosophy are \emph{spurious wakeup} (random wakeup~\cite[\S~8]{Buhr05a}) and \emph{barging} (signals-as-hints~\cite[\S~8]{Buhr05a}), where one is a consequence of the other, \ie, once there is spurious wakeup, signals-as-hints follow.
     335Two concurrency violations of this philosophy are \emph{spurious wakeup} (random wakeup~\cite[\S~8]{Buhr05a}) and \emph{barging} (signals-as-hints~\cite[\S~8]{Buhr05a}), where one is a consequence of the other, \ie once there is spurious wakeup, signals-as-hints follow.
    330336However, spurious wakeup is \emph{not} a foundational concurrency property~\cite[\S~8]{Buhr05a}, it is a performance design choice.
    331337Similarly, signals-as-hints are often a performance decision.
     
    337343Most augmented traditional (Fortran 18~\cite{Fortran18}, Cobol 14~\cite{Cobol14}, Ada 12~\cite{Ada12}, Java 11~\cite{Java11}) and new languages (Go~\cite{Go}, Rust~\cite{Rust}, and D~\cite{D}), except \CC, diverge from C with different syntax and semantics, only interoperate indirectly with C, and are not systems languages, for those with managed memory.
    338344As a result, there is a significant learning curve to move to these languages, and C legacy-code must be rewritten.
    339 While \CC, like \CFA, takes an evolutionary approach to extend C, \CC's constantly growing complex and interdependent features-set (\eg, objects, inheritance, templates, etc.) mean idiomatic \CC code is difficult to use from C, and C programmers must expend significant effort learning \CC.
     345While \CC, like \CFA, takes an evolutionary approach to extend C, \CC's constantly growing complex and interdependent features-set (\eg objects, inheritance, templates, etc.) mean idiomatic \CC code is difficult to use from C, and C programmers must expend significant effort learning \CC.
    340346Hence, rewriting and retraining costs for these languages, even \CC, are prohibitive for companies with a large C software-base.
    341347\CFA with its orthogonal feature-set, its high-performance runtime, and direct access to all existing C libraries circumvents these problems.
     
    367373\section{Stateful Function}
    368374
    369 The stateful function is an old idea~\cite{Conway63,Marlin80} that is new again~\cite{C++20Coroutine19}, where execution is temporarily suspended and later resumed, \eg, plugin, device driver, finite-state machine.
     375The stateful function is an old idea~\cite{Conway63,Marlin80} that is new again~\cite{C++20Coroutine19}, where execution is temporarily suspended and later resumed, \eg plugin, device driver, finite-state machine.
    370376Hence, a stateful function may not end when it returns to its caller, allowing it to be restarted with the data and execution location present at the point of suspension.
    371377This capability is accomplished by retaining a data/execution \emph{closure} between invocations.
    372 If the closure is fixed size, we call it a \emph{generator} (or \emph{stackless}), and its control flow is restricted, \eg, suspending outside the generator is prohibited.
    373 If the closure is variably sized, we call it a \emph{coroutine} (or \emph{stackful}), and as the names implies, often implemented with a separate stack with no programming restrictions.
     378If the closure is fixed size, we call it a \emph{generator} (or \emph{stackless}), and its control flow is restricted, \eg suspending outside the generator is prohibited.
     379If the closure is variable size, we call it a \emph{coroutine} (or \emph{stackful}), and as the names implies, often implemented with a separate stack with no programming restrictions.
    374380Hence, refactoring a stackless coroutine may require changing it to stackful.
    375 A foundational property of all \emph{stateful functions} is that resume/suspend \emph{do not} cause incremental stack growth, \ie, resume/suspend operations are remembered through the closure not the stack.
     381A foundational property of all \emph{stateful functions} is that resume/suspend \emph{do not} cause incremental stack growth, \ie resume/suspend operations are remembered through the closure not the stack.
    376382As well, activating a stateful function is \emph{asymmetric} or \emph{symmetric}, identified by resume/suspend (no cycles) and resume/resume (cycles).
    377383A fixed closure activated by modified call/return is faster than a variable closure activated by context switching.
    378 Additionally, any storage management for the closure (especially in unmanaged languages, \ie, no garbage collection) must also be factored into design and performance.
     384Additionally, any storage management for the closure (especially in unmanaged languages, \ie no garbage collection) must also be factored into design and performance.
    379385Therefore, selecting between stackless and stackful semantics is a tradeoff between programming requirements and performance, where stackless is faster and stackful is more general.
    380386Note, creation cost is amortized across usage, so activation cost is usually the dominant factor.
     
    648654\end{center}
    649655The example takes advantage of resuming a generator in the constructor to prime the loops so the first character sent for formatting appears inside the nested loops.
    650 The destructor provides a newline if formatted text ends with a full line.
     656The destructor provides a newline, if formatted text ends with a full line.
    651657Figure~\ref{f:CFormatSim} shows the C implementation of the \CFA input generator with one additional field and the computed @goto@.
    652658For contrast, Figure~\ref{f:PythonFormatter} shows the equivalent Python format generator with the same properties as the Fibonacci generator.
     
    669675In contrast, the execution state is large, with one @resume@ and seven @suspend@s.
    670676Hence, the key benefits of the generator are correctness, safety, and maintenance because the execution states are transcribed directly into the programming language rather than using a table-driven approach.
    671 Because FSMs can be complex and frequently occur in important domains, direct support of the generator is crucial in a system programming language.
     677Because FSMs can be complex and frequently occur in important domains, direct generator support is important in a system programming language.
    672678
    673679\begin{figure}
     
    796802This semantics is basically a tail-call optimization, which compilers already perform.
    797803The example shows the assembly code to undo the generator's entry code before the direct jump.
    798 This assembly code depends on what entry code is generated, specifically if there are local variables, and the level of optimization.
     804This assembly code depends on what entry code is generated, specifically if there are local variables and the level of optimization.
    799805To provide this new calling convention requires a mechanism built into the compiler, which is beyond the scope of \CFA at this time.
    800806Nevertheless, it is possible to hand generate any symmetric generators for proof of concept and performance testing.
     
    27192725Each benchmark experiment is run 31 times.
    27202726All omitted tests for other languages are functionally identical to the \CFA tests and available online~\cite{CforallBenchMarks}.
    2721 
     2727% tar --exclude=.deps --exclude=Makefile --exclude=Makefile.in --exclude=c.c --exclude=cxx.cpp --exclude=fetch_add.c -cvhf benchmark.tar benchmark
    27222728
    27232729\paragraph{Object Creation}
     
    27492755\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
    27502756\CFA Coroutine Lazy             & 14.3          & 14.3          & 0.32          \\
    2751 \CFA Coroutine Eager    & 2203.7        & 2205.6        & 26.03         \\
     2757\CFA Coroutine Eager    & 522.8         & 525.3         & 5.81          \\
    27522758\CFA Thread                             & 1257.8        & 1291.2        & 86.19         \\
    27532759\uC Coroutine                   & 92.2          & 91.4          & 1.58          \\
  • doc/user/user.tex

    r1f1c102 rf53acdf8  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Sat Jun 15 16:29:45 2019
    14 %% Update Count     : 3847
     13%% Last Modified On : Sat Jul 13 18:36:18 2019
     14%% Update Count     : 3876
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    26972697\subsection{Expressions}
    26982698
     2699% Change order of expression evaluation.
     2700% http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0145r2.pdf
     2701
    26992702Multiple-return-value functions provide \CFA with a new syntax for expressing a combination of expressions in the return statement and a combination of types in a function signature.
    27002703These notions are generalized to provide \CFA with \newterm{tuple expression}s and \newterm{tuple type}s.
     
    33463349
    33473350
    3348 \section{I/O Stream Library}
    3349 \label{s:IOStreamLibrary}
     3351\section{Stream I/O Library}
     3352\label{s:StreamIOLibrary}
    33503353\index{input/output stream library}
    33513354\index{stream library}
    33523355
    3353 The goal of \CFA input/output (I/O) is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way.
    3354 \CFA I/O combines ideas from C ©printf©, \CC, and Python.
    3355 I/O can be unformatted or formatted.
    3356 Unformatted means \CFA selects the output or input format for values that match with the type of a variable.
    3357 Formatted means additional information is specified to augment how an output or input of value is interpreted.
    3358 \CFA formatting is a cross between C ©printf© and \CC ©cout© manipulators.
     3356The goal of \CFA stream input/output (I/O) is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way.
     3357Stream I/O can be implicitly or explicitly formatted.
     3358Implicit formatting means \CFA selects the output or input format for values that match with the type of a variable.
     3359Explicit formatting means additional information is specified to augment how an output or input of value is interpreted.
     3360\CFA formatting is a cross between C ©printf© and \CC ©cout© manipulators, and Python implicit spacing and newline.
     3361Specifically:
    33593362\begin{itemize}
    33603363\item
    3361 ©printf© format codes are dense, making them difficult to read and remember.
     3364©printf©/Python format codes are dense, making them difficult to read and remember.
    33623365\CFA/\CC format manipulators are named, making them easier to read and remember.
    33633366\item
    3364 ©printf© separates format codes from associated variables, making it difficult to match codes with variables.
     3367©printf©/Python separates format codes from associated variables, making it difficult to match codes with variables.
    33653368\CFA/\CC co-locate codes with associated variables, where \CFA has the tighter binding.
    33663369\item
    3367 Format manipulators in \CC have global rather than local effect, except ©setw©.
     3370Format manipulators in \CFA have local effect, whereas \CC have global effect, except ©setw©.
    33683371Hence, it is common programming practice to toggle manipulators on and then back to the default to prevent downstream side-effects.
    33693372Without this programming style, errors occur when moving prints, as manipulator effects incorrectly flow into the new location.
    33703373(To guarantee no side-effects, manipulator values must be saved and restored across function calls.)
     3374\item
     3375\CFA has more sophisticated implicit spacing between values than Python, plus implicit newline at the end of a print.
    33713376\end{itemize}
    33723377The \CFA header file for the I/O library is \Indexc{fstream.hfa}.
    33733378
    3374 For unformatted output, the common case is printing a sequence of variables separated by whitespace.
     3379For implicit formatted output, the common case is printing a series of variables separated by whitespace.
    33753380\begin{cquote}
    3376 \begin{tabular}{@{}l@{\hspace{3em}}l@{}}
    3377 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{\CC}}      \\
     3381\begin{tabular}{@{}l@{\hspace{2em}}l@{\hspace{2em}}l@{}}
     3382\multicolumn{1}{c@{\hspace{2em}}}{\textbf{\CFA}}        & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{\CC}}       & \multicolumn{1}{c}{\textbf{Python}}   \\
    33783383\begin{cfa}
    33793384int x = 1, y = 2, z = 3;
     
    33853390cout << x ®<< " "® << y ®<< " "® << z << endl;
    33863391\end{cfa}
     3392&
     3393\begin{cfa}
     3394x = 1;  y = 2;  z = 3
     3395print( x, y, z )
     3396\end{cfa}
    33873397\\
     3398\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     33991® ®2® ®3
     3400\end{cfa}
     3401&
    33883402\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    338934031® ®2® ®3
     
    34293443There is a weak similarity between the \CFA logical-or operator and the \Index{Shell pipe-operator} for moving data, where data flows in the correct direction for input but the opposite direction for output.
    34303444
    3431 For unformatter input, the common case is reading a sequence of values separated by whitespace, where the type of an input constant must match with the type of the input variable.
     3445For implicit formatted input, the common case is reading a sequence of values separated by whitespace, where the type of an input constant must match with the type of the input variable.
    34323446\begin{cquote}
    34333447\begin{lrbox}{\LstBox}
     
    34363450\end{cfa}
    34373451\end{lrbox}
    3438 \begin{tabular}{@{}l@{\hspace{3em}}l@{}}
     3452\begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{3em}}l@{}}
    34393453\multicolumn{1}{@{}l@{}}{\usebox\LstBox} \\
    3440 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{\CC}}      \\
     3454\multicolumn{1}{c@{\hspace{2em}}}{\textbf{\CFA}}        & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{\CC}}       & \multicolumn{1}{c}{\textbf{Python}}   \\
    34413455\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    34423456sin | x | y | z;
     
    34463460cin >> x >> y >> z;
    34473461\end{cfa}
     3462&
     3463\begin{cfa}[aboveskip=0pt,belowskip=0pt]
     3464x = int(input());  y = float(input());  z = input();
     3465\end{cfa}
    34483466\\
    34493467\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    34503468®1® ®2.5® ®A®
     3469
     3470
    34513471\end{cfa}
    34523472&
    34533473\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    34543474®1® ®2.5® ®A®
     3475
     3476
     3477\end{cfa}
     3478&
     3479\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     3480®1®
     3481®2.5®
     3482®A®
    34553483\end{cfa}
    34563484\end{tabular}
     
    34813509
    34823510\item
    3483 A separator does not appear before or after a null (empty) C string.
     3511A separator does not appear before or after a null (empty) C string, which is a local mechanism to disable insertion of the separator character.
    34843512\begin{cfa}
    34853513sout | 1 | "" | 2 | "" | 3;
    34863514123
    34873515\end{cfa}
    3488 which is a local mechanism to disable insertion of the separator character.
    34893516
    34903517\item
    34913518{\lstset{language=CFA,deletedelim=**[is][]{¢}{¢}}
    3492 A seperator does not appear before a C string starting with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@
     3519A separator does not appear before a C string starting with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@, where \lstinline[basicstyle=\tt]@»@ is a closing citation mark.
    34933520\begin{cfa}[belowskip=0pt]
    34943521sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x"
     
    349835251®,® x 2®.® x 3®;® x 4®!® x 5®?® x 6®%® x 7§\color{red}\textcent§ x 8®»® x 9®)® x 10®]® x 11®}® x
    34993526\end{cfa}}%
    3500 where \lstinline[basicstyle=\tt]@»@ is a closing citation mark.
    3501 
    3502 \item
    3503 A separator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off,basicstyle=\tt]@([{=$£¥¡¿«@
     3527
     3528\item
     3529A separator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off,basicstyle=\tt]@([{=$£¥¡¿«@, where \lstinline[basicstyle=\tt]@¡¿@ are inverted opening exclamation and question marks, and \lstinline[basicstyle=\tt]@«@ is an opening citation mark.
    35043530%$
    35053531\begin{cfa}[mathescape=off]
     
    35123538\end{cfa}
    35133539%$
    3514 where \lstinline[basicstyle=\tt]@¡¿@ are inverted opening exclamation and question marks, and \lstinline[basicstyle=\tt]@«@ is an opening citation mark.
    35153540
    35163541\item
     
    36263651The tuple separator also responses to being turned on and off.
    36273652\begin{cfa}[belowskip=0pt]
    3628 sout | t1 | sepOff | t2; §\C{// locally turn on/off implicit separator
     3653sout | t1 | sepOff | t2; §\C{// turn off implicit separator for the next item
    36293654\end{cfa}
    36303655\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    36503675\subsection{Newline Manipulators}
    36513676
    3652 The following \Index{manipulator} controls \Index{newline separation} for input and output.
     3677The following \Index{manipulators} control \Index{newline separation} for input and output.
    36533678
    36543679For input:
     
    370537300b0 0b11011 0b11011 0b11011 0b11011
    37063731sout | bin( -27HH ) | bin( -27H ) | bin( -27 ) | bin( -27L );
    3707 0b11100101 0b1111111111100101 0b11111111111111111111111111100101 0b(58 1s)100101
     37320b11100101 0b1111111111100101 0b11111111111111111111111111100101 0b®(58 1s)®100101
    37083733\end{cfa}
    37093734
     
    37483773
    37493774\item
    3750 \Indexc{nobase}( integer )\index{manipulator!nobase@©nobase©} do not precede ©bin©, ©oct©, ©hex© with ©0b©/©0B©, ©0©, or ©0x©/©0X©. Printing the base is the default.
     3775\Indexc{nobase}( integer )\index{manipulator!nobase@©nobase©} do not precede ©bin©, ©oct©, ©hex© with ©0b©/©0B©, ©0©, or ©0x©/©0X©.
     3776Printing the base is the default.
    37513777\begin{cfa}[belowskip=0pt]
    37523778sout | nobase( bin( 27 ) ) | nobase( oct( 27 ) ) | nobase( hex( 27 ) );
     
    37823808®  ®4.000000 ® ®4.000000 4.000000
    37833809®  ®ab ® ®ab ab
    3784     ab    ab ab
    37853810\end{cfa}
    37863811If the value is larger, it is printed without truncation, ignoring the ©minimum©.
  • driver/cfa.cc

    r1f1c102 rf53acdf8  
    405405                args[nargs] = "--undefined=__cfaabi_appready_startup";
    406406                nargs += 1;
    407                 args[nargs] = "-Xlinker";
    408                 nargs += 1;
    409                 args[nargs] = "--undefined=__cfaabi_dbg_record";
    410                 nargs += 1;
    411407
    412408                // include the cfa library in case it's needed
     
    414410                nargs += 1;
    415411                args[nargs] = ( *new string( string("-Wl,-rpath," ) + libdir + (intree ? "/src/.libs" : "")) ).c_str();
     412                nargs += 1;
     413                args[nargs] = "-Wl,--push-state,--as-needed";
     414                nargs += 1;
     415                args[nargs] = "-lcfathread";
     416                nargs += 1;
     417                args[nargs] = "-Wl,--pop-state";
    416418                nargs += 1;
    417419                args[nargs] = "-lcfa";
  • libcfa/prelude/builtins.c

    r1f1c102 rf53acdf8  
    1010// Created On       : Fri Jul 21 16:21:03 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Mar 26 23:10:36 2019
    13 // Update Count     : 95
     12// Last Modified On : Tue Jun 25 18:06:52 2019
     13// Update Count     : 97
    1414//
    1515
     
    4949void abort( const char fmt[], ... ) __attribute__ (( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ ));
    5050
    51 // increment/decrement unification
     51// implicit increment, decrement if += defined, and implicit not if != defined
    5252
    5353static inline {
     
    6363        forall( dtype DT | sized(DT) | { void ?{}( DT &, DT ); void ^?{}( DT & ); DT & ?-=?( DT &, one_t ); } )
    6464        DT & ?--( DT & x ) { DT tmp = x; x -= 1; return tmp; }
     65
     66        forall( dtype DT | { int ?!=?( const DT &, zero_t ); } )
     67        int !?( const DT & x ) { return !( x != 0 ); }
    6568} // distribution
    6669
  • libcfa/src/Makefile.am

    r1f1c102 rf53acdf8  
    1111## Created On       : Sun May 31 08:54:01 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Tue Jul 24 17:25:39 2018
    14 ## Update Count     : 240
     13## Last Modified On : Mon Jul 15 22:43:27 2019
     14## Update Count     : 241
    1515###############################################################################
    1616
     
    2222
    2323libdir = ${CFA_LIBDIR}
    24 lib_LTLIBRARIES =  libcfa.la
     24lib_LTLIBRARIES = libcfa.la libcfathread.la
    2525
    2626VPATH += :../prelude
     
    4141          containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa
    4242
    43 # not all platforms support concurrency, add option do disable it
    44 headers_nosrc += concurrency/invoke.h
    45 headers += concurrency/coroutine.hfa concurrency/thread.hfa concurrency/kernel.hfa concurrency/monitor.hfa concurrency/mutex.hfa
    46 
    4743libsrc = startup.cfa interpose.cfa bits/debug.cfa assert.cfa exception.c virtual.c heap.cfa ${headers:.hfa=.cfa}
    4844
    4945# not all platforms support concurrency, add option do disable it
    50 libsrc += concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa concurrency/invoke.c concurrency/preemption.cfa
     46thread_headers_nosrc = concurrency/invoke.h
     47thread_headers = concurrency/coroutine.hfa concurrency/thread.hfa concurrency/kernel.hfa concurrency/monitor.hfa concurrency/mutex.hfa
     48thread_libsrc = concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa concurrency/invoke.c concurrency/preemption.cfa ${thread_headers:.hfa=.cfa}
    5149else
    5250headers =
     51thread_headers =
    5352headers_nosrc =
     53thread_headers_nosrc =
    5454libsrc =
    5555endif
     
    6464$(libobjs) : @CFACC@ @CFACPP@ prelude.cfa
    6565
     66thread_libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(thread_libsrc))))
     67$(thread_libobjs) : @CFACC@ @CFACPP@ prelude.cfa
     68
    6669
    6770# .deps inclusion is not done automatically by automake for new languages
     
    7275
    7376-include $(libdeps)
     77
     78thread_libdeps = $(join \
     79        $(addsuffix $(DEPDIR)/ , $(dir $(thread_libobjs) ) ), \
     80        $(notdir ${thread_libobjs:.lo=.Plo}) \
     81)
     82
     83-include $(thread_libdeps)
     84
    7485
    7586prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@
     
    8596libcfa_la_LDFLAGS = -version-info @CFA_VERSION@
    8697
     98libcfathread_la_SOURCES = ${thread_libsrc}
     99libcfathread_la_LDFLAGS = -version-info @CFA_VERSION@
     100
    87101stdhdr = $(shell find $(srcdir)/stdhdr -type f -printf "%p ")
    88102
    89103cfa_includedir = $(CFA_INCDIR)
    90 nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc}
     104nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc} ${thread_headers} ${thread_headers_nosrc}
    91105
    92106#----------------------------------------------------------------------------------------------------------------
  • libcfa/src/Makefile.in

    r1f1c102 rf53acdf8  
    142142        time.cfa stdlib.cfa common.cfa containers/maybe.cfa \
    143143        containers/pair.cfa containers/result.cfa \
    144         containers/vector.cfa concurrency/coroutine.cfa \
    145         concurrency/thread.cfa concurrency/kernel.cfa \
    146         concurrency/monitor.cfa concurrency/mutex.cfa \
    147         concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa \
    148         concurrency/invoke.c concurrency/preemption.cfa
     144        containers/vector.cfa
    149145am__dirstamp = $(am__leading_dot)dirstamp
    150146@BUILDLIB_TRUE@am__objects_1 = fstream.lo iostream.lo iterator.lo \
     
    152148@BUILDLIB_TRUE@ common.lo containers/maybe.lo \
    153149@BUILDLIB_TRUE@ containers/pair.lo containers/result.lo \
    154 @BUILDLIB_TRUE@ containers/vector.lo concurrency/coroutine.lo \
    155 @BUILDLIB_TRUE@ concurrency/thread.lo concurrency/kernel.lo \
    156 @BUILDLIB_TRUE@ concurrency/monitor.lo concurrency/mutex.lo
     150@BUILDLIB_TRUE@ containers/vector.lo
    157151@BUILDLIB_TRUE@am__objects_2 = startup.lo interpose.lo bits/debug.lo \
    158152@BUILDLIB_TRUE@ assert.lo exception.lo virtual.lo heap.lo \
    159 @BUILDLIB_TRUE@ $(am__objects_1) \
    160 @BUILDLIB_TRUE@ concurrency/CtxSwitch-@ARCHITECTURE@.lo \
    161 @BUILDLIB_TRUE@ concurrency/alarm.lo concurrency/invoke.lo \
    162 @BUILDLIB_TRUE@ concurrency/preemption.lo
     153@BUILDLIB_TRUE@ $(am__objects_1)
    163154am_libcfa_la_OBJECTS = prelude.lo $(am__objects_2)
    164155libcfa_la_OBJECTS = $(am_libcfa_la_OBJECTS)
     
    170161        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
    171162        $(libcfa_la_LDFLAGS) $(LDFLAGS) -o $@
     163libcfathread_la_LIBADD =
     164am__libcfathread_la_SOURCES_DIST =  \
     165        concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa \
     166        concurrency/invoke.c concurrency/preemption.cfa \
     167        concurrency/coroutine.cfa concurrency/thread.cfa \
     168        concurrency/kernel.cfa concurrency/monitor.cfa \
     169        concurrency/mutex.cfa
     170@BUILDLIB_TRUE@am__objects_3 = concurrency/coroutine.lo \
     171@BUILDLIB_TRUE@ concurrency/thread.lo concurrency/kernel.lo \
     172@BUILDLIB_TRUE@ concurrency/monitor.lo concurrency/mutex.lo
     173@BUILDLIB_TRUE@am__objects_4 =  \
     174@BUILDLIB_TRUE@ concurrency/CtxSwitch-@ARCHITECTURE@.lo \
     175@BUILDLIB_TRUE@ concurrency/alarm.lo concurrency/invoke.lo \
     176@BUILDLIB_TRUE@ concurrency/preemption.lo $(am__objects_3)
     177am_libcfathread_la_OBJECTS = $(am__objects_4)
     178libcfathread_la_OBJECTS = $(am_libcfathread_la_OBJECTS)
     179libcfathread_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
     180        $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
     181        $(AM_CFLAGS) $(CFLAGS) $(libcfathread_la_LDFLAGS) $(LDFLAGS) \
     182        -o $@
    172183AM_V_P = $(am__v_P_@AM_V@)
    173184am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
     
    214225am__v_CCLD_0 = @echo "  CCLD    " $@;
    215226am__v_CCLD_1 =
    216 SOURCES = $(libcfa_la_SOURCES)
    217 DIST_SOURCES = $(am__libcfa_la_SOURCES_DIST)
     227SOURCES = $(libcfa_la_SOURCES) $(libcfathread_la_SOURCES)
     228DIST_SOURCES = $(am__libcfa_la_SOURCES_DIST) \
     229        $(am__libcfathread_la_SOURCES_DIST)
    218230am__can_run_installinfo = \
    219231  case $$AM_UPDATE_INFO_DIR in \
     
    225237        limits.hfa rational.hfa time.hfa stdlib.hfa common.hfa \
    226238        containers/maybe.hfa containers/pair.hfa containers/result.hfa \
    227         containers/vector.hfa concurrency/coroutine.hfa \
     239        containers/vector.hfa math.hfa gmp.hfa time_t.hfa \
     240        bits/align.hfa bits/containers.hfa bits/defs.hfa \
     241        bits/debug.hfa bits/locks.hfa concurrency/coroutine.hfa \
    228242        concurrency/thread.hfa concurrency/kernel.hfa \
    229         concurrency/monitor.hfa concurrency/mutex.hfa math.hfa gmp.hfa \
    230         time_t.hfa bits/align.hfa bits/containers.hfa bits/defs.hfa \
    231         bits/debug.hfa bits/locks.hfa concurrency/invoke.h
     243        concurrency/monitor.hfa concurrency/mutex.hfa \
     244        concurrency/invoke.h
    232245HEADERS = $(nobase_cfa_include_HEADERS)
    233246am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
     
    421434am__v_UPP_0 = @echo "  UPP     " $@;
    422435am__v_UPP_1 =
    423 lib_LTLIBRARIES = libcfa.la
     436lib_LTLIBRARIES = libcfa.la libcfathread.la
    424437
    425438# AM_CFLAGS for all cfa source
     
    433446
    434447#----------------------------------------------------------------------------------------------------------------
     448@BUILDLIB_TRUE@headers_nosrc = math.hfa gmp.hfa time_t.hfa bits/align.hfa bits/containers.hfa bits/defs.hfa bits/debug.hfa bits/locks.hfa
     449@BUILDLIB_FALSE@headers =
     450@BUILDLIB_TRUE@headers = fstream.hfa iostream.hfa iterator.hfa limits.hfa rational.hfa time.hfa stdlib.hfa common.hfa \
     451@BUILDLIB_TRUE@   containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa
     452
     453@BUILDLIB_FALSE@libsrc =
     454@BUILDLIB_TRUE@libsrc = startup.cfa interpose.cfa bits/debug.cfa assert.cfa exception.c virtual.c heap.cfa ${headers:.hfa=.cfa}
     455@BUILDLIB_FALSE@thread_headers_nosrc =
    435456
    436457# not all platforms support concurrency, add option do disable it
    437 @BUILDLIB_TRUE@headers_nosrc = math.hfa gmp.hfa time_t.hfa \
    438 @BUILDLIB_TRUE@ bits/align.hfa bits/containers.hfa \
    439 @BUILDLIB_TRUE@ bits/defs.hfa bits/debug.hfa bits/locks.hfa \
    440 @BUILDLIB_TRUE@ concurrency/invoke.h
    441 @BUILDLIB_FALSE@headers =
    442 @BUILDLIB_TRUE@headers = fstream.hfa iostream.hfa iterator.hfa \
    443 @BUILDLIB_TRUE@ limits.hfa rational.hfa time.hfa stdlib.hfa \
    444 @BUILDLIB_TRUE@ common.hfa containers/maybe.hfa \
    445 @BUILDLIB_TRUE@ containers/pair.hfa containers/result.hfa \
    446 @BUILDLIB_TRUE@ containers/vector.hfa concurrency/coroutine.hfa \
    447 @BUILDLIB_TRUE@ concurrency/thread.hfa concurrency/kernel.hfa \
    448 @BUILDLIB_TRUE@ concurrency/monitor.hfa concurrency/mutex.hfa
    449 @BUILDLIB_FALSE@libsrc =
    450 
    451 # not all platforms support concurrency, add option do disable it
    452 @BUILDLIB_TRUE@libsrc = startup.cfa interpose.cfa bits/debug.cfa \
    453 @BUILDLIB_TRUE@ assert.cfa exception.c virtual.c heap.cfa \
    454 @BUILDLIB_TRUE@ ${headers:.hfa=.cfa} \
    455 @BUILDLIB_TRUE@ concurrency/CtxSwitch-@ARCHITECTURE@.S \
    456 @BUILDLIB_TRUE@ concurrency/alarm.cfa concurrency/invoke.c \
    457 @BUILDLIB_TRUE@ concurrency/preemption.cfa
     458@BUILDLIB_TRUE@thread_headers_nosrc = concurrency/invoke.h
     459@BUILDLIB_FALSE@thread_headers =
     460@BUILDLIB_TRUE@thread_headers = concurrency/coroutine.hfa concurrency/thread.hfa concurrency/kernel.hfa concurrency/monitor.hfa concurrency/mutex.hfa
     461@BUILDLIB_TRUE@thread_libsrc = concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa concurrency/invoke.c concurrency/preemption.cfa ${thread_headers:.hfa=.cfa}
    458462
    459463#----------------------------------------------------------------------------------------------------------------
     
    463467# add dependency of cfa files
    464468libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(libsrc))))
     469thread_libobjs = $(addsuffix .lo, $(basename $(filter %.cfa,$(thread_libsrc))))
    465470
    466471# .deps inclusion is not done automatically by automake for new languages
     
    470475)
    471476
     477thread_libdeps = $(join \
     478        $(addsuffix $(DEPDIR)/ , $(dir $(thread_libobjs) ) ), \
     479        $(notdir ${thread_libobjs:.lo=.Plo}) \
     480)
     481
    472482
    473483#----------------------------------------------------------------------------------------------------------------
    474484libcfa_la_SOURCES = prelude.cfa ${libsrc}
    475485libcfa_la_LDFLAGS = -version-info @CFA_VERSION@
     486libcfathread_la_SOURCES = ${thread_libsrc}
     487libcfathread_la_LDFLAGS = -version-info @CFA_VERSION@
    476488stdhdr = $(shell find $(srcdir)/stdhdr -type f -printf "%p ")
    477489cfa_includedir = $(CFA_INCDIR)
    478 nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc}
     490nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc} ${thread_headers} ${thread_headers_nosrc}
    479491all: all-am
    480492
     
    567579containers/vector.lo: containers/$(am__dirstamp) \
    568580        containers/$(DEPDIR)/$(am__dirstamp)
     581
     582libcfa.la: $(libcfa_la_OBJECTS) $(libcfa_la_DEPENDENCIES) $(EXTRA_libcfa_la_DEPENDENCIES)
     583        $(AM_V_CCLD)$(libcfa_la_LINK) -rpath $(libdir) $(libcfa_la_OBJECTS) $(libcfa_la_LIBADD) $(LIBS)
    569584concurrency/$(am__dirstamp):
    570585        @$(MKDIR_P) concurrency
     
    573588        @$(MKDIR_P) concurrency/$(DEPDIR)
    574589        @: > concurrency/$(DEPDIR)/$(am__dirstamp)
     590concurrency/CtxSwitch-@ARCHITECTURE@.lo: concurrency/$(am__dirstamp) \
     591        concurrency/$(DEPDIR)/$(am__dirstamp)
     592concurrency/alarm.lo: concurrency/$(am__dirstamp) \
     593        concurrency/$(DEPDIR)/$(am__dirstamp)
     594concurrency/invoke.lo: concurrency/$(am__dirstamp) \
     595        concurrency/$(DEPDIR)/$(am__dirstamp)
     596concurrency/preemption.lo: concurrency/$(am__dirstamp) \
     597        concurrency/$(DEPDIR)/$(am__dirstamp)
    575598concurrency/coroutine.lo: concurrency/$(am__dirstamp) \
    576599        concurrency/$(DEPDIR)/$(am__dirstamp)
     
    583606concurrency/mutex.lo: concurrency/$(am__dirstamp) \
    584607        concurrency/$(DEPDIR)/$(am__dirstamp)
    585 concurrency/CtxSwitch-@ARCHITECTURE@.lo: concurrency/$(am__dirstamp) \
    586         concurrency/$(DEPDIR)/$(am__dirstamp)
    587 concurrency/alarm.lo: concurrency/$(am__dirstamp) \
    588         concurrency/$(DEPDIR)/$(am__dirstamp)
    589 concurrency/invoke.lo: concurrency/$(am__dirstamp) \
    590         concurrency/$(DEPDIR)/$(am__dirstamp)
    591 concurrency/preemption.lo: concurrency/$(am__dirstamp) \
    592         concurrency/$(DEPDIR)/$(am__dirstamp)
    593 
    594 libcfa.la: $(libcfa_la_OBJECTS) $(libcfa_la_DEPENDENCIES) $(EXTRA_libcfa_la_DEPENDENCIES)
    595         $(AM_V_CCLD)$(libcfa_la_LINK) -rpath $(libdir) $(libcfa_la_OBJECTS) $(libcfa_la_LIBADD) $(LIBS)
     608
     609libcfathread.la: $(libcfathread_la_OBJECTS) $(libcfathread_la_DEPENDENCIES) $(EXTRA_libcfathread_la_DEPENDENCIES)
     610        $(AM_V_CCLD)$(libcfathread_la_LINK) -rpath $(libdir) $(libcfathread_la_OBJECTS) $(libcfathread_la_LIBADD) $(LIBS)
    596611
    597612mostlyclean-compile:
     
    922937        $(am__mv) $$depbase.Tpo $$depbase.Plo
    923938$(libobjs) : @CFACC@ @CFACPP@ prelude.cfa
     939$(thread_libobjs) : @CFACC@ @CFACPP@ prelude.cfa
    924940
    925941-include $(libdeps)
     942
     943-include $(thread_libdeps)
    926944
    927945prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@
  • libcfa/src/bits/containers.hfa

    r1f1c102 rf53acdf8  
    99// Author           : Thierry Delisle
    1010// Created On       : Tue Oct 31 16:38:50 2017
    11 // Last Modified By : --
    12 // Last Modified On : --
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Jun 26 08:52:20 2019
     13// Update Count     : 4
    1414
    1515#pragma once
     
    7878//-----------------------------------------------------------------------------
    7979#ifdef __cforall
    80         forall(dtype TYPE | is_node(TYPE))
     80        forall(dtype TYPE)
    8181        #define T TYPE
    8282#else
     
    9595
    9696#ifdef __cforall
    97         forall(dtype T | is_node(T))
     97        forall(dtype T)
    9898        static inline void ?{}( __stack(T) & this ) {
    9999                (this.top){ NULL };
     
    116116                return top;
    117117        }
     118
     119        forall(dtype T | is_node(T))
     120        static inline int ?!=?( const __stack(T) & this, __attribute__((unused)) zero_t zero ) {
     121                return this.top != 0;
     122        }
    118123#endif
    119124
     
    122127//-----------------------------------------------------------------------------
    123128#ifdef __cforall
    124         forall(dtype TYPE | is_node(TYPE))
     129        forall(dtype TYPE)
    125130        #define T TYPE
    126131#else
     
    141146#ifdef __cforall
    142147
    143         forall(dtype T | is_node(T))
     148        forall(dtype T)
    144149        static inline void ?{}( __queue(T) & this ) with( this ) {
    145150                head{ NULL };
     
    186191
    187192        forall(dtype T | is_node(T))
    188         static inline bool ?!=?( __queue(T) & this, __attribute__((unused)) zero_t zero ) {
     193        static inline int ?!=?( const __queue(T) & this, __attribute__((unused)) zero_t zero ) {
    189194                return this.head != 0;
    190195        }
     
    268273
    269274        forall(dtype T | sized(T))
    270         static inline bool ?!=?( __dllist(T) & this, __attribute__((unused)) zero_t zero ) {
     275        static inline int ?!=?( const __dllist(T) & this, __attribute__((unused)) zero_t zero ) {
    271276                return this.head != 0;
    272277        }
  • libcfa/src/bits/debug.cfa

    r1f1c102 rf53acdf8  
    99// Author           : Thierry Delisle
    1010// Created On       : Thu Mar 30 12:30:01 2017
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 1
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Jul 14 22:17:35 2019
     13// Update Count     : 4
    1414//
    1515
     
    2323}
    2424
    25 enum { buffer_size = 512 };
     25enum { buffer_size = 4096 };
    2626static char buffer[ buffer_size ];
    2727
  • libcfa/src/bits/defs.hfa

    r1f1c102 rf53acdf8  
    4141}
    4242#endif
     43
     44#if defined(__cforall_thread__)
     45#define OPTIONAL_THREAD
     46#else
     47#define OPTIONAL_THREAD __attribute__((weak))
     48#endif
  • libcfa/src/bits/locks.hfa

    r1f1c102 rf53acdf8  
    5050#ifdef __cforall
    5151        extern "C" {
    52                 extern void disable_interrupts();
    53                 extern void enable_interrupts_noPoll();
     52                extern void disable_interrupts() OPTIONAL_THREAD;
     53                extern void enable_interrupts_noPoll() OPTIONAL_THREAD;
    5454
    5555                #ifdef __CFA_DEBUG__
  • libcfa/src/concurrency/alarm.cfa

    r1f1c102 rf53acdf8  
    1313// Update Count     : 67
    1414//
     15
     16#define __cforall_thread__
    1517
    1618extern "C" {
  • libcfa/src/concurrency/coroutine.cfa

    r1f1c102 rf53acdf8  
    1313// Update Count     : 9
    1414//
     15
     16#define __cforall_thread__
    1517
    1618#include "coroutine.hfa"
     
    98100
    99101void ^?{}(coroutine_desc& this) {
    100         if(this.state != Halted && this.state != Start) {
     102        if(this.state != Halted && this.state != Start && this.state != Primed) {
    101103                coroutine_desc * src = TL_GET( this_thread )->curr_cor;
    102104                coroutine_desc * dst = &this;
  • libcfa/src/concurrency/invoke.c

    r1f1c102 rf53acdf8  
    1313// Update Count     : 5
    1414//
     15
     16#define __cforall_thread__
    1517
    1618#include <stdbool.h>
     
    3133extern void __finish_creation( struct thread_desc * );
    3234extern void __leave_thread_monitor( struct thread_desc * this );
    33 extern void disable_interrupts();
     35extern void disable_interrupts() OPTIONAL_THREAD;
    3436extern void enable_interrupts( __cfaabi_dbg_ctx_param );
    3537
  • libcfa/src/concurrency/invoke.h

    r1f1c102 rf53acdf8  
    4646        #ifdef __cforall
    4747        extern "Cforall" {
    48                 static inline struct thread_desc             *& get_next( struct thread_desc             & this );
    49                 static inline struct __condition_criterion_t *& get_next( struct __condition_criterion_t & this );
    50 
    5148                extern thread_local struct KernelThreadData {
    5249                        struct thread_desc    * volatile this_thread;
  • libcfa/src/concurrency/kernel.cfa

    r1f1c102 rf53acdf8  
    1313// Update Count     : 25
    1414//
     15
     16#define __cforall_thread__
    1517
    1618//C Includes
     
    943945        }
    944946)
     947
     948//-----------------------------------------------------------------------------
     949// Debug
     950bool threading_enabled(void) {
     951        return true;
     952}
    945953// Local Variables: //
    946954// mode: c //
  • libcfa/src/concurrency/kernel_private.hfa

    r1f1c102 rf53acdf8  
    2626
    2727extern "C" {
    28         void disable_interrupts();
     28        void disable_interrupts() OPTIONAL_THREAD;
    2929        void enable_interrupts_noPoll();
    3030        void enable_interrupts( __cfaabi_dbg_ctx_param );
  • libcfa/src/concurrency/monitor.cfa

    r1f1c102 rf53acdf8  
    1313// Update Count     : 9
    1414//
     15
     16#define __cforall_thread__
    1517
    1618#include "monitor.hfa"
  • libcfa/src/concurrency/mutex.cfa

    r1f1c102 rf53acdf8  
    1515// Update Count     : 0
    1616//
     17
     18#define __cforall_thread__
    1719
    1820#include "mutex.hfa"
  • libcfa/src/concurrency/preemption.cfa

    r1f1c102 rf53acdf8  
    1313// Update Count     : 37
    1414//
     15
     16#define __cforall_thread__
    1517
    1618#include "preemption.hfa"
  • libcfa/src/concurrency/thread.cfa

    r1f1c102 rf53acdf8  
    1313// Update Count     : 8
    1414//
     15
     16#define __cforall_thread__
    1517
    1618#include "thread.hfa"
  • libcfa/src/fstream.cfa

    r1f1c102 rf53acdf8  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu May 16 08:33:28 2019
    13 // Update Count     : 328
     12// Last Modified On : Mon Jul 15 18:11:26 2019
     13// Update Count     : 349
    1414//
    1515
     
    2424#include <assert.h>
    2525#include <errno.h>                                                                              // errno
     26
     27
     28//*********************************** ofstream ***********************************
     29
    2630
    2731#define IO_MSG "I/O error: "
     
    3741        sepSetCur( os, sepGet( os ) );
    3842        sepSetTuple( os, ", " );
    39 }
     43} // ?{}
    4044
    4145// private
     
    5660void ?{}( ofstream & os, const char * name, const char * mode ) {
    5761        open( os, name, mode );
    58 }
     62} // ?{}
     63
    5964void ?{}( ofstream & os, const char * name ) {
    6065        open( os, name, "w" );
    61 }
     66} // ?{}
    6267
    6368void sepOn( ofstream & os ) { os.sepOnOff = ! getNL( os ); }
     
    95100} // sepSet
    96101
     102void ends( ofstream & os ) {
     103        if ( getANL( os ) ) nl( os );
     104        else setPrt( os, false );                                                       // turn off
     105        if ( &os == &exit ) exit( EXIT_FAILURE );
     106        if ( &os == &abort ) abort();
     107} // ends
     108
    97109int fail( ofstream & os ) {
    98110        return os.file == 0 || ferror( (FILE *)(os.file) );
     
    107119        #ifdef __CFA_DEBUG__
    108120        if ( file == 0 ) {
    109                 abort( IO_MSG "open output file \"%s\", %s", name, strerror( errno ) );
     121                abort | IO_MSG "open output file \"" | name | "\"" | nl | strerror( errno );
    110122        } // if
    111123        #endif // __CFA_DEBUG__
     
    121133
    122134        if ( fclose( (FILE *)(os.file) ) == EOF ) {
    123                 abort( IO_MSG "close output %s", strerror( errno ) );
     135                abort | IO_MSG "close output" | nl | strerror( errno );
    124136        } // if
    125137} // close
     
    127139ofstream & write( ofstream & os, const char * data, size_t size ) {
    128140        if ( fail( os ) ) {
    129                 abort( "attempt write I/O on failed stream\n" );
     141                abort | IO_MSG "attempt write I/O on failed stream";
    130142        } // if
    131143
    132144        if ( fwrite( data, 1, size, (FILE *)(os.file) ) != size ) {
    133                 abort( IO_MSG "write %s", strerror( errno ) );
     145                abort | IO_MSG "write" | nl | strerror( errno );
    134146        } // if
    135147        return os;
     
    142154        if ( len == EOF ) {
    143155                if ( ferror( (FILE *)(os.file) ) ) {
    144                         abort( "invalid write\n" );
     156                        abort | IO_MSG "invalid write";
    145157                } // if
    146158        } // if
     
    153165
    154166static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_) };
    155 ofstream & sout = soutFile;
     167ofstream & sout = soutFile, & stdout = soutFile;
    156168static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_) };
    157 ofstream & serr = serrFile;
    158 
    159 // static ofstream sexitFile = { (FILE *)(&_IO_2_1_stdout_) };
    160 // ofstream & sexit = sexitFile;
    161 // static ofstream sabortFile = { (FILE *)(&_IO_2_1_stderr_) };
    162 // ofstream & sabort = sabortFile;
    163 
    164 void nl( ofstream & os ) {
    165         if ( getANL( os ) ) (ofstream &)(nl( os ));                     // implementation only
    166         else setPrt( os, false );                                                       // turn off
    167 }
    168 
    169 //---------------------------------------
     169ofstream & serr = serrFile, & stderr = serrFile;
     170
     171static ofstream exitFile = { (FILE *)(&_IO_2_1_stdout_) };
     172ofstream & exit = exitFile;
     173static ofstream abortFile = { (FILE *)(&_IO_2_1_stderr_) };
     174ofstream & abort = abortFile;
     175
     176
     177//*********************************** ifstream ***********************************
     178
    170179
    171180// private
     
    173182        is.file = file;
    174183        is.nlOnOff = false;
    175 }
     184} // ?{}
    176185
    177186// public
     
    180189void ?{}( ifstream & is, const char * name, const char * mode ) {
    181190        open( is, name, mode );
    182 }
     191} // ?{}
     192
    183193void ?{}( ifstream & is, const char * name ) {
    184194        open( is, name, "r" );
    185 }
     195} // ?{}
    186196
    187197void nlOn( ifstream & os ) { os.nlOnOff = true; }
     
    201211        #ifdef __CFA_DEBUG__
    202212        if ( file == 0 ) {
    203                 abort( IO_MSG "open input file \"%s\", %s\n", name, strerror( errno ) );
     213                abort | IO_MSG "open input file \"" | name | "\"" | nl | strerror( errno );
    204214        } // if
    205215        #endif // __CFA_DEBUG__
     
    215225
    216226        if ( fclose( (FILE *)(is.file) ) == EOF ) {
    217                 abort( IO_MSG "close input %s", strerror( errno ) );
     227                abort | IO_MSG "close input" | nl | strerror( errno );
    218228        } // if
    219229} // close
     
    221231ifstream & read( ifstream & is, char * data, size_t size ) {
    222232        if ( fail( is ) ) {
    223                 abort( "attempt read I/O on failed stream\n" );
     233                abort | IO_MSG "attempt read I/O on failed stream";
    224234        } // if
    225235
    226236        if ( fread( data, size, 1, (FILE *)(is.file) ) == 0 ) {
    227                 abort( IO_MSG "read %s", strerror( errno ) );
     237                abort | IO_MSG "read" | nl | strerror( errno );
    228238        } // if
    229239        return is;
     
    232242ifstream &ungetc( ifstream & is, char c ) {
    233243        if ( fail( is ) ) {
    234                 abort( "attempt ungetc I/O on failed stream\n" );
     244                abort | IO_MSG "attempt ungetc I/O on failed stream";
    235245        } // if
    236246
    237247        if ( ungetc( c, (FILE *)(is.file) ) == EOF ) {
    238                 abort( IO_MSG "ungetc %s", strerror( errno ) );
     248                abort | IO_MSG "ungetc" | nl | strerror( errno );
    239249        } // if
    240250        return is;
     
    248258        if ( len == EOF ) {
    249259                if ( ferror( (FILE *)(is.file) ) ) {
    250                         abort( "invalid read\n" );
     260                        abort | IO_MSG "invalid read";
    251261                } // if
    252262        } // if
     
    257267
    258268static ifstream sinFile = { (FILE *)(&_IO_2_1_stdin_) };
    259 ifstream & sin = sinFile;
     269ifstream & sin = sinFile, & stdin = sinFile;
    260270
    261271// Local Variables: //
  • libcfa/src/fstream.hfa

    r1f1c102 rf53acdf8  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu May 16 08:34:10 2019
    13 // Update Count     : 157
     12// Last Modified On : Mon Jul 15 18:10:23 2019
     13// Update Count     : 167
    1414//
    1515
     
    1717
    1818#include "iostream.hfa"
     19
     20
     21//*********************************** ofstream ***********************************
     22
    1923
    2024enum { sepSize = 16 };
     
    5660void sepSetTuple( ofstream &, const char * );
    5761
     62void ends( ofstream & os );
    5863int fail( ofstream & );
    5964int flush( ofstream & );
     
    6873void ?{}( ofstream & os, const char * name );
    6974
    70 extern ofstream & sout, & serr;
     75extern ofstream & sout, & stdout, & serr, & stderr;             // aliases
     76extern ofstream & exit, & abort;
    7177
    72 // extern ofstream & sout, & serr, & sexit, & sabort;
    73 // void nl( ofstream & os );
     78
     79//*********************************** ifstream ***********************************
    7480
    7581
     
    96102void ?{}( ifstream & is, const char * name );
    97103
    98 extern ifstream & sin;
     104extern ifstream & sin, & stdin;                                                 // aliases
    99105
    100106// Local Variables: //
  • libcfa/src/gmp.hfa

    r1f1c102 rf53acdf8  
    1010// Created On       : Tue Apr 19 08:43:43 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Apr 20 09:01:52 2019
    13 // Update Count     : 24
     12// Last Modified On : Sat Jul 13 15:25:05 2019
     13// Update Count     : 27
    1414//
    1515
     
    1919
    2020#include <gmp.h>                                                                                // GNU multi-precise integers
    21 #include <fstream.hfa>                                                                          // sout
     21#include <fstream.hfa>                                                                  // sout
    2222
    2323struct Int { mpz_t mpz; };                                                              // wrap GMP implementation
    2424
    25 // constructor
    26 static inline void ?{}( Int & this ) { mpz_init( this.mpz ); }
    27 static inline void ?{}( Int & this, Int init ) { mpz_init_set( this.mpz, init.mpz ); }
    28 static inline void ?{}( Int & this, zero_t ) { mpz_init_set_si( this.mpz, 0 ); }
    29 static inline void ?{}( Int & this, one_t ) { mpz_init_set_si( this.mpz, 1 ); }
    30 static inline void ?{}( Int & this, signed long int init ) { mpz_init_set_si( this.mpz, init ); }
    31 static inline void ?{}( Int & this, unsigned long int init ) { mpz_init_set_ui( this.mpz, init ); }
    32 static inline void ?{}( Int & this, const char * val ) { if ( mpz_init_set_str( this.mpz, val, 0 ) ) abort(); }
    33 static inline void ^?{}( Int & this ) { mpz_clear( this.mpz ); }
    34 
    35 // literal
    36 static inline Int ?`mp( signed long int init ) { return (Int){ init }; }
    37 static inline Int ?`mp( unsigned long int init ) { return (Int){ init }; }
    38 static inline Int ?`mp( const char * init ) { return (Int){ init }; }
    39 
    40 // assignment
    41 static inline Int ?=?( Int & lhs, Int rhs ) { mpz_set( lhs.mpz, rhs.mpz ); return lhs; }
    42 static inline Int ?=?( Int & lhs, long int rhs ) { mpz_set_si( lhs.mpz, rhs ); return lhs; }
    43 static inline Int ?=?( Int & lhs, unsigned long int rhs ) { mpz_set_ui( lhs.mpz, rhs ); return lhs; }
    44 static inline Int ?=?( Int & lhs, const char * rhs ) { if ( mpz_set_str( lhs.mpz, rhs, 0 ) ) { printf( "invalid string conversion\n" ); abort(); } return lhs; }
    45 
    46 static inline char ?=?( char & lhs, Int rhs ) { char val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
    47 static inline short int ?=?( short int & lhs, Int rhs ) { short int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
    48 static inline int ?=?( int & lhs, Int rhs ) { int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
    49 static inline long int ?=?( long int & lhs, Int rhs ) { long int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
    50 static inline unsigned char ?=?( unsigned char & lhs, Int rhs ) { unsigned char val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
    51 static inline unsigned short int ?=?( unsigned short int & lhs, Int rhs ) { unsigned short int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
    52 static inline unsigned int ?=?( unsigned int & lhs, Int rhs ) { unsigned int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
    53 static inline unsigned long int ?=?( unsigned long int & lhs, Int rhs ) { unsigned long int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
    54 
    55 // conversions
    56 static inline long int narrow( Int val ) { return mpz_get_si( val.mpz ); }
    57 static inline unsigned long int narrow( Int val ) { return mpz_get_ui( val.mpz ); }
    58 
    59 // comparison
    60 static inline int ?==?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) == 0; }
    61 static inline int ?==?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; }
    62 static inline int ?==?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; }
    63 static inline int ?==?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; }
    64 static inline int ?==?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; }
    65 
    66 static inline int ?!=?( Int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
    67 static inline int ?!=?( Int oper1, long int oper2 ) { return ! ( oper1 == oper2 ); }
    68 static inline int ?!=?( long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
    69 static inline int ?!=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 == oper2 ); }
    70 static inline int ?!=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
    71 
    72 static inline int ?<?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) < 0; }
    73 static inline int ?<?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; }
    74 static inline int ?<?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; }
    75 static inline int ?<?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; }
    76 static inline int ?<?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; }
    77 
    78 static inline int ?<=?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) <= 0; }
    79 static inline int ?<=?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; }
    80 static inline int ?<=?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; }
    81 static inline int ?<=?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; }
    82 static inline int ?<=?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; }
    83 
    84 static inline int ?>?( Int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
    85 static inline int ?>?( Int oper1, long int oper2 ) { return ! ( oper1 <= oper2 ); }
    86 static inline int ?>?( long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
    87 static inline int ?>?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 <= oper2 ); }
    88 static inline int ?>?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
    89 
    90 static inline int ?>=?( Int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
    91 static inline int ?>=?( Int oper1, long int oper2 ) { return ! ( oper1 < oper2 ); }
    92 static inline int ?>=?( long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
    93 static inline int ?>=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 < oper2 ); }
    94 static inline int ?>=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
    95 
    96 // arithmetic
    97 static inline Int +?( Int oper ) { Int pos; mpz_set( pos.mpz, oper.mpz ); return pos; }
    98 static inline Int -?( Int oper ) { Int neg; mpz_neg( neg.mpz, oper.mpz ); return neg; }
    99 static inline Int ~?( Int oper ) { Int comp; mpz_com( comp.mpz, oper.mpz ); return comp; }
    100 
    101 static inline Int ?&?( Int oper1, Int oper2 ) { Int conjunction; mpz_and( conjunction.mpz, oper1.mpz, oper2.mpz ); return conjunction; }
    102 static inline Int ?&?( Int oper1, long int oper2 ) { Int conjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_and( conjunction.mpz, oper1.mpz, temp.mpz ); return conjunction; }
    103 static inline Int ?&?( long int oper1, Int oper2 ) { Int conjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_and( conjunction.mpz, temp.mpz, oper2.mpz ); return conjunction; }
    104 static inline Int ?&?( Int oper1, unsigned long int oper2 ) { Int conjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_and( conjunction.mpz, oper1.mpz, temp.mpz ); return conjunction; }
    105 static inline Int ?&?( unsigned long int oper1, Int oper2 ) { Int conjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_and( conjunction.mpz, temp.mpz, oper2.mpz ); return conjunction; }
    106 static inline Int ?&=?( Int & lhs, Int rhs ) { return lhs = lhs & rhs; }
    107 
    108 static inline Int ?|?( Int oper1, Int oper2 ) { Int disjunction; mpz_ior( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; }
    109 static inline Int ?|?( Int oper1, long int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
    110 static inline Int ?|?( long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
    111 static inline Int ?|?( Int oper1, unsigned long int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
    112 static inline Int ?|?( unsigned long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
    113 static inline Int ?|=?( Int & lhs, Int rhs ) { return lhs = lhs | rhs; }
    114 
    115 static inline Int ?^?( Int oper1, Int oper2 ) { Int disjunction; mpz_xor( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; }
    116 static inline Int ?^?( Int oper1, long int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
    117 static inline Int ?^?( long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
    118 static inline Int ?^?( Int oper1, unsigned long int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
    119 static inline Int ?^?( unsigned long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
    120 static inline Int ?^=?( Int & lhs, Int rhs ) { return lhs = lhs ^ rhs; }
    121 
    122 static inline Int ?+?( Int addend1, Int addend2 ) { Int sum; mpz_add( sum.mpz, addend1.mpz, addend2.mpz ); return sum; }
    123 static inline Int ?+?( Int addend1, long int addend2 ) { Int sum; if ( addend2 >= 0 ) mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); else mpz_sub_ui( sum.mpz, addend1.mpz, -addend2 ); return sum; }
    124 static inline Int ?+?( long int addend2, Int addend1 ) { Int sum; if ( addend2 >= 0 ) mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); else mpz_sub_ui( sum.mpz, addend1.mpz, -addend2 ); return sum; }
    125 static inline Int ?+?( Int addend1, unsigned long int addend2 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; }
    126 static inline Int ?+?( unsigned long int addend2, Int addend1 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; }
    127 static inline Int ?+=?( Int & lhs, Int rhs ) { return lhs = lhs + rhs; }
    128 static inline Int ?+=?( Int & lhs, long int rhs ) { return lhs = lhs + rhs; }
    129 static inline Int ?+=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs + rhs; }
    130 static inline Int ++?( Int & lhs ) { return lhs += 1; }
    131 static inline Int ?++( Int & lhs ) { Int ret = lhs; lhs += 1; return ret; }
    132 
    133 static inline Int ?-?( Int minuend, Int subtrahend ) { Int diff; mpz_sub( diff.mpz, minuend.mpz, subtrahend.mpz ); return diff; }
    134 static inline Int ?-?( Int minuend, long int subtrahend ) { Int diff; if ( subtrahend >= 0 ) mpz_sub_ui( diff.mpz, minuend.mpz, subtrahend ); else mpz_add_ui( diff.mpz, minuend.mpz, -subtrahend ); return diff; }
    135 static inline Int ?-?( long int minuend, Int subtrahend ) { Int diff; if ( subtrahend >= 0 ) mpz_ui_sub( diff.mpz, minuend, subtrahend.mpz ); else { mpz_add_ui( diff.mpz, subtrahend.mpz, -minuend ); mpz_neg( diff.mpz, diff.mpz ); } return diff; }
    136 static inline Int ?-?( Int minuend, unsigned long int subtrahend ) { Int diff; mpz_sub_ui( diff.mpz, minuend.mpz, subtrahend ); return diff; }
    137 static inline Int ?-?( unsigned long int minuend, Int subtrahend ) { Int diff; mpz_ui_sub( diff.mpz, minuend, subtrahend.mpz ); return diff; }
    138 static inline Int ?-=?( Int & lhs, Int rhs ) { return lhs = lhs - rhs; }
    139 static inline Int ?-=?( Int & lhs, long int rhs ) { return lhs = lhs - rhs; }
    140 static inline Int ?-=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs - rhs; }
    141 static inline Int --?( Int & lhs ) { return lhs -= 1; }
    142 static inline Int ?--( Int & lhs ) { Int ret = lhs; lhs -= 1; return ret; }
    143 
    144 static inline Int ?*?( Int multiplicator, Int multiplicand ) { Int product; mpz_mul( product.mpz, multiplicator.mpz, multiplicand.mpz ); return product; }
    145 static inline Int ?*?( Int multiplicator, long int multiplicand ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; }
    146 static inline Int ?*?( long int multiplicand, Int multiplicator ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; }
    147 static inline Int ?*?( Int multiplicator, unsigned long int multiplicand ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; }
    148 static inline Int ?*?( unsigned long int multiplicand, Int multiplicator ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; }
    149 static inline Int ?*=?( Int & lhs, Int rhs ) { return lhs = lhs * rhs; }
    150 static inline Int ?*=?( Int & lhs, long int rhs ) { return lhs = lhs * rhs; }
    151 static inline Int ?*=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs * rhs; }
    152 
    153 // some code for operators "/" and "%" taken from g++ gmpxx.h
    154 static inline Int ?/?( Int dividend, Int divisor ) { Int quotient; mpz_tdiv_q( quotient.mpz, dividend.mpz, divisor.mpz ); return quotient; }
    155 static inline Int ?/?( Int dividend, unsigned long int divisor ) { Int quotient; mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, divisor ); return quotient; }
    156 static inline Int ?/?( unsigned long int dividend, Int divisor ) {
    157         Int quotient;
    158     if ( mpz_sgn( divisor.mpz ) >= 0 ) {
    159                 if ( mpz_fits_ulong_p( divisor.mpz ) )
    160                         mpz_set_ui( quotient.mpz, dividend / mpz_get_ui( divisor.mpz ) );
    161                 else
    162                         mpz_set_ui( quotient.mpz, 0 );
    163         } else {
    164                 mpz_neg( quotient.mpz, divisor.mpz );
    165                 if ( mpz_fits_ulong_p( quotient.mpz ) ) {
    166                         mpz_set_ui( quotient.mpz, dividend / mpz_get_ui( quotient.mpz ) );
     25static inline {
     26        // constructor
     27        void ?{}( Int & this ) { mpz_init( this.mpz ); }
     28        void ?{}( Int & this, Int init ) { mpz_init_set( this.mpz, init.mpz ); }
     29        void ?{}( Int & this, zero_t ) { mpz_init_set_si( this.mpz, 0 ); }
     30        void ?{}( Int & this, one_t ) { mpz_init_set_si( this.mpz, 1 ); }
     31        void ?{}( Int & this, signed long int init ) { mpz_init_set_si( this.mpz, init ); }
     32        void ?{}( Int & this, unsigned long int init ) { mpz_init_set_ui( this.mpz, init ); }
     33        void ?{}( Int & this, const char * val ) { if ( mpz_init_set_str( this.mpz, val, 0 ) ) abort(); }
     34        void ^?{}( Int & this ) { mpz_clear( this.mpz ); }
     35
     36        // literal
     37        Int ?`mp( signed long int init ) { return (Int){ init }; }
     38        Int ?`mp( unsigned long int init ) { return (Int){ init }; }
     39        Int ?`mp( const char * init ) { return (Int){ init }; }
     40
     41        // assignment
     42        Int ?=?( Int & lhs, Int rhs ) { mpz_set( lhs.mpz, rhs.mpz ); return lhs; }
     43        Int ?=?( Int & lhs, long int rhs ) { mpz_set_si( lhs.mpz, rhs ); return lhs; }
     44        Int ?=?( Int & lhs, unsigned long int rhs ) { mpz_set_ui( lhs.mpz, rhs ); return lhs; }
     45        Int ?=?( Int & lhs, const char * rhs ) { if ( mpz_set_str( lhs.mpz, rhs, 0 ) ) { abort | "invalid string conversion"; } return lhs; }
     46
     47        char ?=?( char & lhs, Int rhs ) { char val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
     48        short int ?=?( short int & lhs, Int rhs ) { short int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
     49        int ?=?( int & lhs, Int rhs ) { int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
     50        long int ?=?( long int & lhs, Int rhs ) { long int val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
     51        unsigned char ?=?( unsigned char & lhs, Int rhs ) { unsigned char val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
     52        unsigned short int ?=?( unsigned short int & lhs, Int rhs ) { unsigned short int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
     53        unsigned int ?=?( unsigned int & lhs, Int rhs ) { unsigned int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
     54        unsigned long int ?=?( unsigned long int & lhs, Int rhs ) { unsigned long int val = mpz_get_ui( rhs.mpz ); lhs = val; return lhs; }
     55
     56        // conversions
     57        long int narrow( Int val ) { return mpz_get_si( val.mpz ); }
     58        unsigned long int narrow( Int val ) { return mpz_get_ui( val.mpz ); }
     59
     60        // comparison
     61        int ?==?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) == 0; }
     62        int ?==?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; }
     63        int ?==?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) == 0; }
     64        int ?==?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; }
     65        int ?==?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) == 0; }
     66
     67        int ?!=?( Int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
     68        int ?!=?( Int oper1, long int oper2 ) { return ! ( oper1 == oper2 ); }
     69        int ?!=?( long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
     70        int ?!=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 == oper2 ); }
     71        int ?!=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 == oper2 ); }
     72
     73        int ?<?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) < 0; }
     74        int ?<?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; }
     75        int ?<?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) < 0; }
     76        int ?<?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; }
     77        int ?<?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) < 0; }
     78
     79        int ?<=?( Int oper1, Int oper2 ) { return mpz_cmp( oper1.mpz, oper2.mpz ) <= 0; }
     80        int ?<=?( Int oper1, long int oper2 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; }
     81        int ?<=?( long int oper2, Int oper1 ) { return mpz_cmp_si( oper1.mpz, oper2 ) <= 0; }
     82        int ?<=?( Int oper1, unsigned long int oper2 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; }
     83        int ?<=?( unsigned long int oper2, Int oper1 ) { return mpz_cmp_ui( oper1.mpz, oper2 ) <= 0; }
     84
     85        int ?>?( Int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
     86        int ?>?( Int oper1, long int oper2 ) { return ! ( oper1 <= oper2 ); }
     87        int ?>?( long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
     88        int ?>?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 <= oper2 ); }
     89        int ?>?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 <= oper2 ); }
     90
     91        int ?>=?( Int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
     92        int ?>=?( Int oper1, long int oper2 ) { return ! ( oper1 < oper2 ); }
     93        int ?>=?( long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
     94        int ?>=?( Int oper1, unsigned long int oper2 ) { return ! ( oper1 < oper2 ); }
     95        int ?>=?( unsigned long int oper1, Int oper2 ) { return ! ( oper1 < oper2 ); }
     96
     97        // arithmetic
     98        Int +?( Int oper ) { Int pos; mpz_set( pos.mpz, oper.mpz ); return pos; }
     99        Int -?( Int oper ) { Int neg; mpz_neg( neg.mpz, oper.mpz ); return neg; }
     100        Int ~?( Int oper ) { Int comp; mpz_com( comp.mpz, oper.mpz ); return comp; }
     101
     102        Int ?&?( Int oper1, Int oper2 ) { Int conjunction; mpz_and( conjunction.mpz, oper1.mpz, oper2.mpz ); return conjunction; }
     103        Int ?&?( Int oper1, long int oper2 ) { Int conjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_and( conjunction.mpz, oper1.mpz, temp.mpz ); return conjunction; }
     104        Int ?&?( long int oper1, Int oper2 ) { Int conjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_and( conjunction.mpz, temp.mpz, oper2.mpz ); return conjunction; }
     105        Int ?&?( Int oper1, unsigned long int oper2 ) { Int conjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_and( conjunction.mpz, oper1.mpz, temp.mpz ); return conjunction; }
     106        Int ?&?( unsigned long int oper1, Int oper2 ) { Int conjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_and( conjunction.mpz, temp.mpz, oper2.mpz ); return conjunction; }
     107        Int ?&=?( Int & lhs, Int rhs ) { return lhs = lhs & rhs; }
     108
     109        Int ?|?( Int oper1, Int oper2 ) { Int disjunction; mpz_ior( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; }
     110        Int ?|?( Int oper1, long int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
     111        Int ?|?( long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
     112        Int ?|?( Int oper1, unsigned long int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
     113        Int ?|?( unsigned long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
     114        Int ?|=?( Int & lhs, Int rhs ) { return lhs = lhs | rhs; }
     115
     116        Int ?^?( Int oper1, Int oper2 ) { Int disjunction; mpz_xor( disjunction.mpz, oper1.mpz, oper2.mpz ); return disjunction; }
     117        Int ?^?( Int oper1, long int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
     118        Int ?^?( long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_si( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
     119        Int ?^?( Int oper1, unsigned long int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper2 ); mpz_ior( disjunction.mpz, oper1.mpz, temp.mpz ); return disjunction; }
     120        Int ?^?( unsigned long int oper1, Int oper2 ) { Int disjunction, temp; mpz_set_ui( temp.mpz, oper1 ); mpz_ior( disjunction.mpz, temp.mpz, oper2.mpz ); return disjunction; }
     121        Int ?^=?( Int & lhs, Int rhs ) { return lhs = lhs ^ rhs; }
     122
     123        Int ?+?( Int addend1, Int addend2 ) { Int sum; mpz_add( sum.mpz, addend1.mpz, addend2.mpz ); return sum; }
     124        Int ?+?( Int addend1, long int addend2 ) { Int sum; if ( addend2 >= 0 ) mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); else mpz_sub_ui( sum.mpz, addend1.mpz, -addend2 ); return sum; }
     125        Int ?+?( long int addend2, Int addend1 ) { Int sum; if ( addend2 >= 0 ) mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); else mpz_sub_ui( sum.mpz, addend1.mpz, -addend2 ); return sum; }
     126        Int ?+?( Int addend1, unsigned long int addend2 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; }
     127        Int ?+?( unsigned long int addend2, Int addend1 ) { Int sum; mpz_add_ui( sum.mpz, addend1.mpz, addend2 ); return sum; }
     128        Int ?+=?( Int & lhs, Int rhs ) { return lhs = lhs + rhs; }
     129        Int ?+=?( Int & lhs, long int rhs ) { return lhs = lhs + rhs; }
     130        Int ?+=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs + rhs; }
     131        Int ++?( Int & lhs ) { return lhs += 1; }
     132        Int ?++( Int & lhs ) { Int ret = lhs; lhs += 1; return ret; }
     133
     134        Int ?-?( Int minuend, Int subtrahend ) { Int diff; mpz_sub( diff.mpz, minuend.mpz, subtrahend.mpz ); return diff; }
     135        Int ?-?( Int minuend, long int subtrahend ) { Int diff; if ( subtrahend >= 0 ) mpz_sub_ui( diff.mpz, minuend.mpz, subtrahend ); else mpz_add_ui( diff.mpz, minuend.mpz, -subtrahend ); return diff; }
     136        Int ?-?( long int minuend, Int subtrahend ) { Int diff; if ( subtrahend >= 0 ) mpz_ui_sub( diff.mpz, minuend, subtrahend.mpz ); else { mpz_add_ui( diff.mpz, subtrahend.mpz, -minuend ); mpz_neg( diff.mpz, diff.mpz ); } return diff; }
     137        Int ?-?( Int minuend, unsigned long int subtrahend ) { Int diff; mpz_sub_ui( diff.mpz, minuend.mpz, subtrahend ); return diff; }
     138        Int ?-?( unsigned long int minuend, Int subtrahend ) { Int diff; mpz_ui_sub( diff.mpz, minuend, subtrahend.mpz ); return diff; }
     139        Int ?-=?( Int & lhs, Int rhs ) { return lhs = lhs - rhs; }
     140        Int ?-=?( Int & lhs, long int rhs ) { return lhs = lhs - rhs; }
     141        Int ?-=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs - rhs; }
     142        Int --?( Int & lhs ) { return lhs -= 1; }
     143        Int ?--( Int & lhs ) { Int ret = lhs; lhs -= 1; return ret; }
     144
     145        Int ?*?( Int multiplicator, Int multiplicand ) { Int product; mpz_mul( product.mpz, multiplicator.mpz, multiplicand.mpz ); return product; }
     146        Int ?*?( Int multiplicator, long int multiplicand ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; }
     147        Int ?*?( long int multiplicand, Int multiplicator ) { Int product; mpz_mul_si( product.mpz, multiplicator.mpz, multiplicand ); return product; }
     148        Int ?*?( Int multiplicator, unsigned long int multiplicand ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; }
     149        Int ?*?( unsigned long int multiplicand, Int multiplicator ) { Int product; mpz_mul_ui( product.mpz, multiplicator.mpz, multiplicand ); return product; }
     150        Int ?*=?( Int & lhs, Int rhs ) { return lhs = lhs * rhs; }
     151        Int ?*=?( Int & lhs, long int rhs ) { return lhs = lhs * rhs; }
     152        Int ?*=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs * rhs; }
     153
     154        // some code for operators "/" and "%" taken from g++ gmpxx.h
     155        Int ?/?( Int dividend, Int divisor ) { Int quotient; mpz_tdiv_q( quotient.mpz, dividend.mpz, divisor.mpz ); return quotient; }
     156        Int ?/?( Int dividend, unsigned long int divisor ) { Int quotient; mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, divisor ); return quotient; }
     157        Int ?/?( unsigned long int dividend, Int divisor ) {
     158                Int quotient;
     159                if ( mpz_sgn( divisor.mpz ) >= 0 ) {
     160                        if ( mpz_fits_ulong_p( divisor.mpz ) )
     161                                mpz_set_ui( quotient.mpz, dividend / mpz_get_ui( divisor.mpz ) );
     162                        else
     163                                mpz_set_ui( quotient.mpz, 0 );
     164                } else {
     165                        mpz_neg( quotient.mpz, divisor.mpz );
     166                        if ( mpz_fits_ulong_p( quotient.mpz ) ) {
     167                                mpz_set_ui( quotient.mpz, dividend / mpz_get_ui( quotient.mpz ) );
     168                                mpz_neg( quotient.mpz, quotient.mpz );
     169                        } else
     170                                mpz_set_ui( quotient.mpz, 0 );
     171                } // if
     172                return quotient;
     173        } // ?/?
     174        Int ?/?( Int dividend, long int divisor ) {
     175                Int quotient;
     176                if ( divisor >= 0 )
     177                        mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, divisor );
     178                else {
     179                        mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, -divisor );
    167180                        mpz_neg( quotient.mpz, quotient.mpz );
    168                 } else
    169                         mpz_set_ui( quotient.mpz, 0 );
    170         } // if
    171         return quotient;
    172 } // ?/?
    173 static inline Int ?/?( Int dividend, long int divisor ) {
    174         Int quotient;
    175     if ( divisor >= 0 )
    176                 mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, divisor );
    177     else {
    178                 mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, -divisor );
    179                 mpz_neg( quotient.mpz, quotient.mpz );
    180         } // if
    181         return quotient;
    182 } // ?/?
    183 static inline Int ?/?( long int dividend, Int divisor ) {
    184         Int quotient;
    185     if ( mpz_fits_slong_p( divisor.mpz ) )
    186                 mpz_set_si( quotient.mpz, dividend / mpz_get_si( divisor.mpz ) );
    187     else {
    188         // if divisor is bigger than a long then the quotient must be zero, unless dividend==LONG_MIN and
    189         // dividend==-LONG_MIN in which case the quotient is -1
    190         mpz_set_si( quotient.mpz, mpz_cmpabs_ui( divisor.mpz, (dividend >= 0 ? dividend : -dividend)) == 0 ? -1 : 0 );
    191         } // if
    192         return quotient;
    193 } // ?/?
    194 static inline Int ?/=?( Int & lhs, Int rhs ) { return lhs = lhs / rhs; }
    195 static inline Int ?/=?( Int & lhs, long int rhs ) { return lhs = lhs / rhs; }
    196 static inline Int ?/=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs / rhs; }
    197 
    198 static inline [ Int, Int ] div( Int dividend, Int divisor ) { Int quotient, remainder; mpz_fdiv_qr( quotient.mpz, remainder.mpz, dividend.mpz, divisor.mpz ); return [ quotient, remainder ]; }
    199 static inline [ Int, Int ] div( Int dividend, unsigned long int divisor ) { Int quotient, remainder; mpz_fdiv_qr_ui( quotient.mpz, remainder.mpz, dividend.mpz, divisor ); return [ quotient, remainder ]; }
    200 
    201 static inline Int ?%?( Int dividend, Int divisor ) { Int remainder; mpz_tdiv_r( remainder.mpz, dividend.mpz, divisor.mpz ); return remainder; }
    202 static inline Int ?%?( Int dividend, unsigned long int divisor ) { Int remainder; mpz_tdiv_r_ui( remainder.mpz, dividend.mpz, divisor ); return remainder; }
    203 static inline Int ?%?( unsigned long int dividend, Int divisor ) {
    204         Int remainder;
    205     if ( mpz_sgn( divisor.mpz ) >= 0 ) {
    206                 if ( mpz_fits_ulong_p( divisor.mpz ) )
    207                         mpz_set_ui( remainder.mpz, dividend % mpz_get_ui( divisor.mpz ) );
    208                 else
    209                         mpz_set_ui( remainder.mpz, dividend );
    210         } else {
    211                 mpz_neg( remainder.mpz, divisor.mpz );
    212                 if ( mpz_fits_ulong_p( remainder.mpz ) )
    213                         mpz_set_ui( remainder.mpz, dividend % mpz_get_ui( remainder.mpz ) );
    214                 else
    215                         mpz_set_ui( remainder.mpz, dividend );
    216         } // if
    217         return remainder;
    218 } // ?%?
    219 static inline Int ?%?( Int dividend, long int divisor ) {
    220         Int remainder;
    221     mpz_tdiv_r_ui( remainder.mpz, dividend.mpz, (divisor >= 0 ? divisor : -divisor));
    222         return remainder;
    223 } // ?%?
    224 static inline Int ?%?( long int dividend, Int divisor ) {
    225         Int remainder;
    226     if ( mpz_fits_slong_p( divisor.mpz ) )
    227                 mpz_set_si( remainder.mpz, dividend % mpz_get_si( divisor.mpz ) );
    228         else {
    229                 // if divisor is bigger than a long then the remainder is dividend unchanged, unless dividend==LONG_MIN and
    230                 // dividend==-LONG_MIN in which case the remainder is 0
    231         mpz_set_si( remainder.mpz, mpz_cmpabs_ui( divisor.mpz, (dividend >= 0 ? dividend : -dividend)) == 0 ? 0 : dividend);
    232         } // if
    233         return remainder;
    234 } // ?%?
    235 static inline Int ?%=?( Int & lhs, Int rhs ) { return lhs = lhs % rhs; }
    236 static inline Int ?%=?( Int & lhs, long int rhs ) { return lhs = lhs % rhs; }
    237 static inline Int ?%=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs % rhs; }
    238 
    239 static inline Int ?<<?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_mul_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; }
    240 static inline Int ?<<=?( Int & lhs, mp_bitcnt_t shift ) { return lhs = lhs << shift; }
    241 static inline Int ?>>?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_fdiv_q_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; }
    242 static inline Int ?>>=?( Int & lhs, mp_bitcnt_t shift ) { return lhs = lhs >> shift; }
    243 
    244 // number functions
    245 static inline Int abs( Int oper ) { Int positive; mpz_abs( positive.mpz, oper.mpz ); return positive; }
    246 static inline Int fact( unsigned long int N ) { Int factorial; mpz_fac_ui( factorial.mpz, N ); return factorial; }
    247 static inline Int gcd( Int oper1, Int oper2 ) { Int gcdret; mpz_gcd( gcdret.mpz, oper1.mpz, oper2.mpz ); return gcdret; }
    248 static inline Int pow( Int base, unsigned long int exponent ) { Int power; mpz_pow_ui( power.mpz, base.mpz, exponent ); return power; }
    249 static inline Int pow( unsigned long int base, unsigned long int exponent ) { Int power; mpz_ui_pow_ui( power.mpz, base, exponent ); return power; }
    250 static inline void srandom( gmp_randstate_t state ) { gmp_randinit_default( state ); }
    251 static inline Int random( gmp_randstate_t state, mp_bitcnt_t n ) { Int rand; mpz_urandomb( rand.mpz, state, n ); return rand; }
    252 static inline Int random( gmp_randstate_t state, Int n ) { Int rand; mpz_urandomm( rand.mpz, state, n.mpz ); return rand; }
    253 static inline Int random( gmp_randstate_t state, mp_size_t max_size ) { Int rand; mpz_random( rand.mpz, max_size ); return rand; }
    254 static inline int sgn( Int oper ) { return mpz_sgn( oper.mpz ); }
    255 static inline Int sqrt( Int oper ) { Int root; mpz_sqrt( root.mpz, oper.mpz ); return root; }
    256 
    257 // I/O
    258 static inline forall( dtype istype | istream( istype ) )
    259 istype & ?|?( istype & is, Int & mp ) {
    260         gmp_scanf( "%Zd", &mp );
    261         return is;
    262 } // ?|?
    263 
    264 static inline forall( dtype ostype | ostream( ostype ) ) {
    265         ostype & ?|?( ostype & os, Int mp ) {
    266                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    267                 gmp_printf( "%Zd", mp.mpz );
    268                 sepOn( os );
    269                 return os;
     181                } // if
     182                return quotient;
     183        } // ?/?
     184        Int ?/?( long int dividend, Int divisor ) {
     185                Int quotient;
     186                if ( mpz_fits_slong_p( divisor.mpz ) )
     187                        mpz_set_si( quotient.mpz, dividend / mpz_get_si( divisor.mpz ) );
     188                else {
     189                        // if divisor is bigger than a long then the quotient must be zero, unless dividend==LONG_MIN and
     190                        // dividend==-LONG_MIN in which case the quotient is -1
     191                        mpz_set_si( quotient.mpz, mpz_cmpabs_ui( divisor.mpz, (dividend >= 0 ? dividend : -dividend)) == 0 ? -1 : 0 );
     192                } // if
     193                return quotient;
     194        } // ?/?
     195        Int ?/=?( Int & lhs, Int rhs ) { return lhs = lhs / rhs; }
     196        Int ?/=?( Int & lhs, long int rhs ) { return lhs = lhs / rhs; }
     197        Int ?/=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs / rhs; }
     198
     199        [ Int, Int ] div( Int dividend, Int divisor ) { Int quotient, remainder; mpz_fdiv_qr( quotient.mpz, remainder.mpz, dividend.mpz, divisor.mpz ); return [ quotient, remainder ]; }
     200        [ Int, Int ] div( Int dividend, unsigned long int divisor ) { Int quotient, remainder; mpz_fdiv_qr_ui( quotient.mpz, remainder.mpz, dividend.mpz, divisor ); return [ quotient, remainder ]; }
     201
     202        Int ?%?( Int dividend, Int divisor ) { Int remainder; mpz_tdiv_r( remainder.mpz, dividend.mpz, divisor.mpz ); return remainder; }
     203        Int ?%?( Int dividend, unsigned long int divisor ) { Int remainder; mpz_tdiv_r_ui( remainder.mpz, dividend.mpz, divisor ); return remainder; }
     204        Int ?%?( unsigned long int dividend, Int divisor ) {
     205                Int remainder;
     206                if ( mpz_sgn( divisor.mpz ) >= 0 ) {
     207                        if ( mpz_fits_ulong_p( divisor.mpz ) )
     208                                mpz_set_ui( remainder.mpz, dividend % mpz_get_ui( divisor.mpz ) );
     209                        else
     210                                mpz_set_ui( remainder.mpz, dividend );
     211                } else {
     212                        mpz_neg( remainder.mpz, divisor.mpz );
     213                        if ( mpz_fits_ulong_p( remainder.mpz ) )
     214                                mpz_set_ui( remainder.mpz, dividend % mpz_get_ui( remainder.mpz ) );
     215                        else
     216                                mpz_set_ui( remainder.mpz, dividend );
     217                } // if
     218                return remainder;
     219        } // ?%?
     220        Int ?%?( Int dividend, long int divisor ) {
     221                Int remainder;
     222                mpz_tdiv_r_ui( remainder.mpz, dividend.mpz, (divisor >= 0 ? divisor : -divisor));
     223                return remainder;
     224        } // ?%?
     225        Int ?%?( long int dividend, Int divisor ) {
     226                Int remainder;
     227                if ( mpz_fits_slong_p( divisor.mpz ) )
     228                        mpz_set_si( remainder.mpz, dividend % mpz_get_si( divisor.mpz ) );
     229                else {
     230                        // if divisor is bigger than a long then the remainder is dividend unchanged, unless dividend==LONG_MIN and
     231                        // dividend==-LONG_MIN in which case the remainder is 0
     232                        mpz_set_si( remainder.mpz, mpz_cmpabs_ui( divisor.mpz, (dividend >= 0 ? dividend : -dividend)) == 0 ? 0 : dividend);
     233                } // if
     234                return remainder;
     235        } // ?%?
     236        Int ?%=?( Int & lhs, Int rhs ) { return lhs = lhs % rhs; }
     237        Int ?%=?( Int & lhs, long int rhs ) { return lhs = lhs % rhs; }
     238        Int ?%=?( Int & lhs, unsigned long int rhs ) { return lhs = lhs % rhs; }
     239
     240        Int ?<<?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_mul_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; }
     241        Int ?<<=?( Int & lhs, mp_bitcnt_t shift ) { return lhs = lhs << shift; }
     242        Int ?>>?( Int shiften, mp_bitcnt_t shift ) { Int shifted; mpz_fdiv_q_2exp( shifted.mpz, shiften.mpz, shift ); return shifted; }
     243        Int ?>>=?( Int & lhs, mp_bitcnt_t shift ) { return lhs = lhs >> shift; }
     244
     245        // number functions
     246        Int abs( Int oper ) { Int positive; mpz_abs( positive.mpz, oper.mpz ); return positive; }
     247        Int fact( unsigned long int N ) { Int factorial; mpz_fac_ui( factorial.mpz, N ); return factorial; }
     248        Int gcd( Int oper1, Int oper2 ) { Int gcdret; mpz_gcd( gcdret.mpz, oper1.mpz, oper2.mpz ); return gcdret; }
     249        Int pow( Int base, unsigned long int exponent ) { Int power; mpz_pow_ui( power.mpz, base.mpz, exponent ); return power; }
     250        Int pow( unsigned long int base, unsigned long int exponent ) { Int power; mpz_ui_pow_ui( power.mpz, base, exponent ); return power; }
     251        void srandom( gmp_randstate_t state ) { gmp_randinit_default( state ); }
     252        Int random( gmp_randstate_t state, mp_bitcnt_t n ) { Int rand; mpz_urandomb( rand.mpz, state, n ); return rand; }
     253        Int random( gmp_randstate_t state, Int n ) { Int rand; mpz_urandomm( rand.mpz, state, n.mpz ); return rand; }
     254        Int random( gmp_randstate_t state, mp_size_t max_size ) { Int rand; mpz_random( rand.mpz, max_size ); return rand; }
     255        int sgn( Int oper ) { return mpz_sgn( oper.mpz ); }
     256        Int sqrt( Int oper ) { Int root; mpz_sqrt( root.mpz, oper.mpz ); return root; }
     257
     258        // I/O
     259        forall( dtype istype | istream( istype ) )
     260                istype & ?|?( istype & is, Int & mp ) {
     261                gmp_scanf( "%Zd", &mp );
     262                return is;
    270263        } // ?|?
    271264
    272         void ?|?( ostype & os, Int mp ) {
    273                 (ostype)(os | mp); nl( os );
    274         } // ?|?
     265        forall( dtype ostype | ostream( ostype ) ) {
     266                ostype & ?|?( ostype & os, Int mp ) {
     267                        if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     268                        gmp_printf( "%Zd", mp.mpz );
     269                        sepOn( os );
     270                        return os;
     271                } // ?|?
     272
     273                void ?|?( ostype & os, Int mp ) {
     274                        (ostype)(os | mp); ends( os );
     275                } // ?|?
     276        } // distribution
    275277} // distribution
    276278
  • libcfa/src/interpose.cfa

    r1f1c102 rf53acdf8  
    1010// Created On       : Wed Mar 29 16:10:31 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat May  5 11:37:35 2018
    13 // Update Count     : 111
     12// Last Modified On : Sun Jul 14 22:57:16 2019
     13// Update Count     : 116
    1414//
    1515
     
    8181//=============================================================================================
    8282
    83 void sigHandler_segv ( __CFA_SIGPARMS__ );
    84 void sigHandler_ill  ( __CFA_SIGPARMS__ );
    85 void sigHandler_fpe  ( __CFA_SIGPARMS__ );
    86 void sigHandler_abort( __CFA_SIGPARMS__ );
    87 void sigHandler_term ( __CFA_SIGPARMS__ );
     83void sigHandler_segv( __CFA_SIGPARMS__ );
     84void sigHandler_ill ( __CFA_SIGPARMS__ );
     85void sigHandler_fpe ( __CFA_SIGPARMS__ );
     86void sigHandler_abrt( __CFA_SIGPARMS__ );
     87void sigHandler_term( __CFA_SIGPARMS__ );
    8888
    8989struct {
     
    110110                __cfaabi_sigaction( SIGILL , sigHandler_ill  , SA_SIGINFO );
    111111                __cfaabi_sigaction( SIGFPE , sigHandler_fpe  , SA_SIGINFO );
    112                 __cfaabi_sigaction( SIGABRT, sigHandler_abort, SA_SIGINFO | SA_RESETHAND);
     112                __cfaabi_sigaction( SIGABRT, sigHandler_abrt, SA_SIGINFO | SA_RESETHAND);
    113113                __cfaabi_sigaction( SIGTERM, sigHandler_term , SA_SIGINFO );
    114114                __cfaabi_sigaction( SIGINT , sigHandler_term , SA_SIGINFO );
     
    204204                        if ( *p == '(' ) {
    205205                                name = p;
    206                         }
    207                         else if ( *p == '+' ) {
     206                        } else if ( *p == '+' ) {
    208207                                offset_begin = p;
    209                         }
    210                         else if ( *p == ')' ) {
     208                        } else if ( *p == ')' ) {
    211209                                offset_end = p;
    212210                                break;
     
    223221
    224222                        __cfaabi_dbg_bits_print_nolock( "(%i) %s : %s + %s %s\n", frameNo, messages[i], name, offset_begin, offset_end);
    225                 }
    226                 // otherwise, print the whole line
    227                 else {
     223                } else {                                                                                // otherwise, print the whole line
    228224                        __cfaabi_dbg_bits_print_nolock( "(%i) %s\n", frameNo, messages[i] );
    229225                }
     
    258254}
    259255
    260 void sigHandler_abort( __CFA_SIGPARMS__ ) {
     256void sigHandler_abrt( __CFA_SIGPARMS__ ) {
    261257        __cfaabi_backtrace();
    262258
  • libcfa/src/iostream.cfa

    r1f1c102 rf53acdf8  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun 13 17:21:10 2019
    13 // Update Count     : 812
     12// Last Modified On : Sat Jul 13 08:07:59 2019
     13// Update Count     : 821
    1414//
    1515
     
    3030
    3131
    32 //*********************************** Ostream ***********************************
     32//*********************************** ostream ***********************************
    3333
    3434
     
    4040        } // ?|?
    4141        void ?|?( ostype & os, zero_t z ) {
    42                 (ostype &)(os | z); nl( os );
     42                (ostype &)(os | z); ends( os );
    4343        } // ?|?
    4444
     
    4949        } // ?|?
    5050        void ?|?( ostype & os, one_t o ) {
    51                 (ostype &)(os | o); nl( os );
     51                (ostype &)(os | o); ends( os );
    5252        } // ?|?
    5353
     
    5858        } // ?|?
    5959        void ?|?( ostype & os, bool b ) {
    60                 (ostype &)(os | b); nl( os );
     60                (ostype &)(os | b); ends( os );
    6161        } // ?|?
    6262
     
    6767        } // ?|?
    6868        void ?|?( ostype & os, char c ) {
    69                 (ostype &)(os | c); nl( os );
     69                (ostype &)(os | c); ends( os );
    7070        } // ?|?
    7171
     
    7676        } // ?|?
    7777        void ?|?( ostype & os, signed char sc ) {
    78                 (ostype &)(os | sc); nl( os );
     78                (ostype &)(os | sc); ends( os );
    7979        } // ?|?
    8080
     
    8585        } // ?|?
    8686        void ?|?( ostype & os, unsigned char usc ) {
    87                 (ostype &)(os | usc); nl( os );
     87                (ostype &)(os | usc); ends( os );
    8888        } // ?|?
    8989
     
    9494        } // ?|?
    9595        void & ?|?( ostype & os, short int si ) {
    96                 (ostype &)(os | si); nl( os );
     96                (ostype &)(os | si); ends( os );
    9797        } // ?|?
    9898
     
    103103        } // ?|?
    104104        void & ?|?( ostype & os, unsigned short int usi ) {
    105                 (ostype &)(os | usi); nl( os );
     105                (ostype &)(os | usi); ends( os );
    106106        } // ?|?
    107107
     
    112112        } // ?|?
    113113        void & ?|?( ostype & os, int i ) {
    114                 (ostype &)(os | i); nl( os );
     114                (ostype &)(os | i); ends( os );
    115115        } // ?|?
    116116
     
    121121        } // ?|?
    122122        void & ?|?( ostype & os, unsigned int ui ) {
    123                 (ostype &)(os | ui); nl( os );
     123                (ostype &)(os | ui); ends( os );
    124124        } // ?|?
    125125
     
    130130        } // ?|?
    131131        void & ?|?( ostype & os, long int li ) {
    132                 (ostype &)(os | li); nl( os );
     132                (ostype &)(os | li); ends( os );
    133133        } // ?|?
    134134
     
    139139        } // ?|?
    140140        void & ?|?( ostype & os, unsigned long int uli ) {
    141                 (ostype &)(os | uli); nl( os );
     141                (ostype &)(os | uli); ends( os );
    142142        } // ?|?
    143143
     
    148148        } // ?|?
    149149        void & ?|?( ostype & os, long long int lli ) {
    150                 (ostype &)(os | lli); nl( os );
     150                (ostype &)(os | lli); ends( os );
    151151        } // ?|?
    152152
     
    157157        } // ?|?
    158158        void & ?|?( ostype & os, unsigned long long int ulli ) {
    159                 (ostype &)(os | ulli); nl( os );
     159                (ostype &)(os | ulli); ends( os );
    160160        } // ?|?
    161161
     
    180180        } // ?|?
    181181        void & ?|?( ostype & os, float f ) {
    182                 (ostype &)(os | f); nl( os );
     182                (ostype &)(os | f); ends( os );
    183183        } // ?|?
    184184
     
    189189        } // ?|?
    190190        void & ?|?( ostype & os, double d ) {
    191                 (ostype &)(os | d); nl( os );
     191                (ostype &)(os | d); ends( os );
    192192        } // ?|?
    193193
     
    198198        } // ?|?
    199199        void & ?|?( ostype & os, long double ld ) {
    200                 (ostype &)(os | ld); nl( os );
     200                (ostype &)(os | ld); ends( os );
    201201        } // ?|?
    202202
     
    210210        } // ?|?
    211211        void & ?|?( ostype & os, float _Complex fc ) {
    212                 (ostype &)(os | fc); nl( os );
     212                (ostype &)(os | fc); ends( os );
    213213        } // ?|?
    214214
     
    222222        } // ?|?
    223223        void & ?|?( ostype & os, double _Complex dc ) {
    224                 (ostype &)(os | dc); nl( os );
     224                (ostype &)(os | dc); ends( os );
    225225        } // ?|?
    226226
     
    234234        } // ?|?
    235235        void & ?|?( ostype & os, long double _Complex ldc ) {
    236                 (ostype &)(os | ldc); nl( os );
     236                (ostype &)(os | ldc); ends( os );
    237237        } // ?|?
    238238
     
    276276        } // ?|?
    277277        void ?|?( ostype & os, const char * str ) {
    278                 (ostype &)(os | str); nl( os );
     278                (ostype &)(os | str); ends( os );
    279279        } // ?|?
    280280
     
    305305        } // ?|?
    306306        void ?|?( ostype & os, const void * p ) {
    307                 (ostype &)(os | p); nl( os );
     307                (ostype &)(os | p); ends( os );
    308308        } // ?|?
    309309
     
    315315        void ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
    316316                (ostype &)(manip( os ));
    317                 if ( getPrt( os ) ) nl( os );                                   // something printed ?
     317                if ( getPrt( os ) ) ends( os );                                 // something printed ?
    318318                setPrt( os, false );                                                    // turn off
    319319        } // ?|?
     
    335335        } // nl
    336336
    337         void nl( ostype & os ) {
    338                 if ( getANL( os ) ) (ostype &)(nl( os ));               // implementation only
    339                 else setPrt( os, false );                                               // turn off
    340         } // nl
    341 
    342337        ostype & nonl( ostype & os ) {
    343338                setPrt( os, false );                                                    // turn off
     
    386381        } // ?|?
    387382        void ?|?( ostype & os, T arg, Params rest ) {
    388                 // (ostype &)(?|?( os, arg, rest )); nl( os );
     383                // (ostype &)(?|?( os, arg, rest )); ends( os );
    389384                (ostype &)(os | arg);                                                   // print first argument
    390385                sepSetCur( os, sepGetTuple( os ) );                             // switch to tuple separator
    391386                (ostype &)(os | rest);                                                  // print remaining arguments
    392387                sepSetCur( os, sepGet( os ) );                                  // switch to regular separator
    393                 nl( os );
     388                ends( os );
    394389        } // ?|?
    395390} // distribution
     
    408403} // distribution
    409404
    410 //*********************************** Manipulators ***********************************
    411 
    412 //*********************************** Integral ***********************************
     405//*********************************** manipulators ***********************************
     406
     407//*********************************** integral ***********************************
    413408
    414409static const char * shortbin[] = { "0", "1", "10", "11", "100", "101", "110", "111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" };
     
    478473                return os; \
    479474        } /* ?|? */ \
    480         void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); nl( os ); } \
     475        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
    481476} // distribution
    482477
     
    492487IntegralFMTImpl( unsigned long long int, 'u', "%    *ll ", "%    *.*ll " )
    493488
    494 //*********************************** Floating Point ***********************************
     489//*********************************** floating point ***********************************
    495490
    496491#define PrintWithDP2( os, format, val, ... ) \
     
    504499                                if ( ! f.flags.left ) { \
    505500                                        buf[i] = '.'; buf[i + 1] = '\0'; \
    506                                         if ( buf[0] == ' ' ) bufbeg = 1; /* decimal point within width */ \
     501                                        if ( buf[0] == ' ' ) bufbeg = 1;        /* decimal point within width */ \
    507502                                } else { \
    508503                                        for ( i = 0; i < len && buf[i] != ' '; i += 1 ); /* trailing blank ? */ \
     
    541536                return os; \
    542537        } /* ?|? */ \
    543         void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); nl( os ); } \
     538        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
    544539} // distribution
    545540
     
    547542FloatingPointFMTImpl( long double, "%    *L ", "%    *.*L " )
    548543
    549 //*********************************** Character ***********************************
     544//*********************************** character ***********************************
    550545
    551546forall( dtype ostype | ostream( ostype ) ) {
    552547        ostype & ?|?( ostype & os, _Ostream_Manip(char) f ) {
    553                 if ( f.base != 'c' ) {                                                          // bespoke binary/octal/hex format
     548                if ( f.base != 'c' ) {                                                  // bespoke binary/octal/hex format
    554549                        _Ostream_Manip(unsigned char) fmtuc @= { f.val, f.wd, f.pc, f.base, {'\0'} };
    555550                        fmtuc.flags.pc = f.flags.pc;
     
    563558
    564559                #define CFMTNP "% * "
    565                 char fmtstr[sizeof(CFMTNP)];                                            // sizeof includes '\0'
     560                char fmtstr[sizeof(CFMTNP)];                                    // sizeof includes '\0'
    566561                memcpy( &fmtstr, CFMTNP, sizeof(CFMTNP) );
    567                 int star = 1;                                                                           // position before first '*'
     562                int star = 1;                                                                   // position before first '*'
    568563
    569564                // Insert flags into spaces before '*', from right to left.
     
    571566                fmtstr[star] = '%';
    572567
    573                 fmtstr[sizeof(CFMTNP)-2] = f.base;                                      // sizeof includes '\0'
     568                fmtstr[sizeof(CFMTNP)-2] = f.base;                              // sizeof includes '\0'
    574569                // printf( "%d %s\n", f.wd, &fmtstr[star] );
    575570                fmt( os, &fmtstr[star], f.wd, f.val );
    576571                return os;
    577572        } // ?|?
    578         void ?|?( ostype & os, _Ostream_Manip(char) f ) { (ostype &)(os | f); nl( os ); }
     573        void ?|?( ostype & os, _Ostream_Manip(char) f ) { (ostype &)(os | f); ends( os ); }
    579574} // distribution
    580575
    581 //*********************************** C String ***********************************
     576//*********************************** C string ***********************************
    582577
    583578forall( dtype ostype | ostream( ostype ) ) {
     
    621616                return os;
    622617        } // ?|?
    623         void ?|?( ostype & os, _Ostream_Manip(const char *) f ) { (ostype &)(os | f); nl( os ); }
     618        void ?|?( ostype & os, _Ostream_Manip(const char *) f ) { (ostype &)(os | f); ends( os ); }
    624619} // distribution
    625620
    626621
    627 //*********************************** Istream ***********************************
     622//*********************************** istream ***********************************
    628623
    629624
     
    636631                else {
    637632                        fprintf( stderr, "invalid Boolean constant\n" );
    638                         abort();
     633                        abort();                                                                        // cannot use abort stream
    639634                } // if
    640635                return is;
     
    644639                char temp;
    645640                for () {
    646                         fmt( is, "%c", &temp );                                                 // must pass pointer through varg to fmt
     641                        fmt( is, "%c", &temp );                                         // must pass pointer through varg to fmt
    647642                        // do not overwrite parameter with newline unless appropriate
    648643                        if ( temp != '\n' || getANL( is ) ) { c = temp; break; }
     
    771766} // distribution
    772767
    773 //*********************************** Manipulators ***********************************
     768//*********************************** manipulators ***********************************
    774769
    775770forall( dtype istype | istream( istype ) )
     
    778773        if ( ! f.s ) {
    779774                // printf( "skip %s %d\n", f.scanset, f.wd );
    780                 if ( f.wd == -1 ) fmt( is, f.scanset, "" ); // no input arguments
     775                if ( f.wd == -1 ) fmt( is, f.scanset, "" );             // no input arguments
    781776                else for ( f.wd ) fmt( is, "%*c" );
    782777                return is;
  • libcfa/src/iostream.hfa

    r1f1c102 rf53acdf8  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun 13 17:20:21 2019
    13 // Update Count     : 325
     12// Last Modified On : Fri Jul 12 12:08:38 2019
     13// Update Count     : 334
    1414//
    1515
     
    1919
    2020
    21 //*********************************** Ostream ***********************************
     21//*********************************** ostream ***********************************
    2222
    2323
     
    4747        void sepSetTuple( ostype &, const char * );                     // set tuple separator to string (15 character maximum)
    4848
     49        void ends( ostype & os );                                                       // end of output statement
    4950        int fail( ostype & );
    5051        int flush( ostype & );
     
    9899        void ?|?( ostype &, unsigned long long int );
    99100
    100         ostype & ?|?( ostype &, float ); // FIX ME: should not be required
    101         void ?|?( ostype &, float ); // FIX ME: should not be required
     101        ostype & ?|?( ostype &, float );
     102        void ?|?( ostype &, float );
    102103        ostype & ?|?( ostype &, double );
    103104        void ?|?( ostype &, double );
     
    126127        void ?|?( ostype &, ostype & (*)( ostype & ) );
    127128        ostype & nl( ostype & );
    128         void nl( ostype & );
    129129        ostype & nonl( ostype & );
    130130        ostype & sep( ostype & );
     
    150150} // distribution
    151151
    152 //*********************************** Manipulators ***********************************
     152//*********************************** manipulators ***********************************
    153153
    154154forall( otype T )
     
    169169}; // _Ostream_Manip
    170170
    171 //*********************************** Integral ***********************************
     171//*********************************** integral ***********************************
    172172
    173173// See 6.7.9. 19) The initialization shall occur in initializer list order, each initializer provided for a particular
     
    207207IntegralFMTDecl( unsigned long long int, 'u' )
    208208
    209 //*********************************** Floating Point ***********************************
     209//*********************************** floating point ***********************************
    210210
    211211// Default suffix for values with no fraction is "."
     
    236236FloatingPointFMTDecl( long double )
    237237
    238 //*********************************** Character ***********************************
     238//*********************************** character ***********************************
    239239
    240240static inline {
     
    253253} // ?|?
    254254
    255 //*********************************** C String ***********************************
     255//*********************************** C string ***********************************
    256256
    257257static inline {
     
    272272
    273273
    274 //*********************************** Istream ***********************************
     274//*********************************** istream ***********************************
    275275
    276276
     
    326326} // distribution
    327327
    328 //*********************************** Manipulators ***********************************
     328//*********************************** manipulators ***********************************
    329329
    330330struct _Istream_Cstr {
     
    403403
    404404
    405 //*********************************** Time ***********************************
     405//*********************************** time ***********************************
    406406
    407407
  • libcfa/src/rational.cfa

    r1f1c102 rf53acdf8  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 28 17:33:03 2019
    13 // Update Count     : 181
     12// Last Modified On : Fri Jul 12 18:12:08 2019
     13// Update Count     : 184
    1414//
    1515
     
    3535        static RationalImpl simplify( RationalImpl & n, RationalImpl & d ) {
    3636                if ( d == (RationalImpl){0} ) {
    37                         abort( "Invalid rational number construction: denominator cannot be equal to 0.\n" );
     37                        abort | "Invalid rational number construction: denominator cannot be equal to 0.";
    3838                } // exit
    3939                if ( d < (RationalImpl){0} ) { d = -d; n = -n; } // move sign to numerator
     
    167167
    168168                void ?|?( ostype & os, Rational(RationalImpl) r ) {
    169                         (ostype &)(os | r); nl( os );
     169                        (ostype &)(os | r); ends( os );
    170170                } // ?|?
    171171        } // distribution
  • libcfa/src/stdlib.cfa

    r1f1c102 rf53acdf8  
    1010// Created On       : Thu Jan 28 17:10:29 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul 12 08:03:59 2018
    13 // Update Count     : 458
     12// Last Modified On : Mon Jun 24 17:34:44 2019
     13// Update Count     : 462
    1414//
    1515
     
    6565forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } )
    6666T * anew( size_t dim, Params p ) {
    67         T *arr = alloc( dim );
     67        T * arr = alloc( dim );
    6868        for ( unsigned int i = 0; i < dim; i += 1 ) {
    6969                (arr[i]){ p };                                                                  // run constructor
     
    252252long double _Complex random( void ) { return (long double)drand48() + (long double _Complex)(drand48() * _Complex_I); }
    253253
     254//---------------------------------------
     255
     256bool threading_enabled(void) __attribute__((weak)) {
     257        return false;
     258}
    254259
    255260// Local Variables: //
  • libcfa/src/stdlib.hfa

    r1f1c102 rf53acdf8  
    1515
    1616#pragma once
     17
     18#include "bits/defs.hfa"
    1719
    1820#include <stdlib.h>                                                                             // *alloc, strto*, ato*
     
    246248#include "common.hfa"
    247249
     250//---------------------------------------
     251
     252extern bool threading_enabled(void) OPTIONAL_THREAD;
     253
    248254// Local Variables: //
    249255// mode: c //
  • libcfa/src/time.cfa

    r1f1c102 rf53acdf8  
    1010// Created On       : Tue Mar 27 13:33:14 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Dec 23 22:57:48 2018
    13 // Update Count     : 57
     12// Last Modified On : Sat Jul 13 08:41:55 2019
     13// Update Count     : 65
    1414//
    1515
    1616#include "time.hfa"
    17 #include "iostream.hfa"
     17#include "fstream.hfa"
    1818#include <stdio.h>                                                                              // snprintf
    1919#include <assert.h>
     
    3737                if ( ns != 0 ) {                                                                // some ?
    3838                        char buf[16];
    39                         (ostype &)(os | nanomsd( ns, buf ));                    // print nanoseconds
     39                        (ostype &)(os | nanomsd( ns, buf ));            // print nanoseconds
    4040                } // if
    4141                return os;
     
    4343
    4444        void ?|?( ostype & os, Duration dur ) with( dur ) {
    45                 (ostype &)(os | dur); nl( os );
     45                (ostype &)(os | dur); ends( os );
    4646        } // ?|?
    4747} // distribution
     
    5252
    5353#ifdef __CFA_DEBUG__
    54 #define CreateFmt "Attempt to create Time( year=%d (>=1970), month=%d (1-12), day=%d (1-31), hour=%d (0-23), min=%d (0-59), sec=%d (0-60), nsec=%d (0-999_999_999), " \
    55         "which exceeds range 00:00:00 UTC, January 1, 1970 to 03:14:07 UTC, January 19, 2038."
     54static void tabort( int year, int month, int day, int hour, int min, int sec, int nsec ) {
     55        abort | "Attempt to create Time( year=" | year | "(>=1970), month=" | month | "(1-12), day=" | day | "(1-31), hour=" | hour | "(0-23), min=" | min | "(0-59), sec=" | sec
     56                  | "(0-60), nsec=" | nsec | "(0-999_999_999), which exceeds range 00:00:00 UTC, January 1, 1970 to 03:14:07 UTC, January 19, 2038.";
     57} // tabort
    5658#endif // __CFA_DEBUG__
    5759
     
    6365#ifdef __CFA_DEBUG__
    6466        if ( month < 1 || 12 < month ) {
    65                 abort( CreateFmt, year, month, day, hour, (int)min, sec, nsec );
     67                tabort( year, month, day, hour, min, sec, nsec );
    6668        } // if
    6769#endif // __CFA_DEBUG__
     
    6971#ifdef __CFA_DEBUG__
    7072        if ( day < 1 || 31 < day ) {
    71                 abort( CreateFmt, year, month, day, hour, (int)min, sec, nsec );
     73                tabort( year, month, day, hour, min, sec, nsec );
    7274        } // if
    7375#endif // __CFA_DEBUG__
     
    7981#ifdef __CFA_DEBUG__
    8082        if ( epochsec == (time_t)-1 ) {
    81                 abort( CreateFmt, year, month, day, hour, (int)min, sec, nsec );
     83                tabort( year, month, day, hour, min, sec, nsec );
    8284        } // if
    8385#endif // __CFA_DEBUG__
     
    8587#ifdef __CFA_DEBUG__
    8688        if ( tv > 2147483647LL * TIMEGRAN ) {                           // between 00:00:00 UTC, January 1, 1970 and 03:14:07 UTC, January 19, 2038.
    87                 abort( CreateFmt, year, month, day, hour, (int)min, sec, nsec );
     89                tabort( year, month, day, hour, min, sec, nsec );
    8890        } // if
    8991#endif // __CFA_DEBUG__
     
    150152                long int ns = (tv < 0 ? -tv : tv) % TIMEGRAN;   // compute nanoseconds
    151153                if ( ns == 0 ) {                                                                // none ?
    152                         (ostype &)(os | buf);                                                   // print date/time/year
     154                        (ostype &)(os | buf);                                           // print date/time/year
    153155                } else {
    154156                        buf[19] = '\0';                                                         // truncate to "Wed Jun 30 21:49:08"
    155157                        char buf2[16];
    156158                        nanomsd( ns, buf2 );                                            // compute nanoseconds
    157                         (ostype &)(os | buf | buf2 | ' ' | &buf[20]);   // print date/time, nanoseconds and year
     159                        (ostype &)(os | buf | buf2 | ' ' | &buf[20]); // print date/time, nanoseconds and year
    158160                } // if
    159161                return os;
     
    161163
    162164        void ?|?( ostype & os, Time time ) with( time ) {
    163                 (ostype &)(os | time); nl( os );
     165                (ostype &)(os | time); ends( os );
    164166        } // ?|?
    165167} // distribution
  • src/AST/Convert.cpp

    r1f1c102 rf53acdf8  
    518518        }
    519519
    520         const ast::Stmt * visit( const ast::WithStmt * node ) override final {
     520        const ast::Decl * visit( const ast::WithStmt * node ) override final {
    521521                if ( inCache( node ) ) return nullptr;
    522522                auto stmt = new WithStmt(
     
    524524                        get<Statement>().accept1( node->stmt )
    525525                );
    526                 return stmtPostamble( stmt, node );
     526                declPostamble( stmt, node );
     527                return nullptr;
    527528        }
    528529
     
    10391040                                get<Expression>().accept1(node->expr),
    10401041                                inCache(node->deleteStmt) ?
    1041                                         this->node :
    1042                                         get<BaseSyntaxNode>().accept1(node->deleteStmt)
     1042                                        strict_dynamic_cast<Declaration*>(this->node) :
     1043                                        get<Declaration>().accept1(node->deleteStmt)
    10431044                        )
    10441045                );
     
    13551356        ast::Node * node = nullptr;
    13561357        /// cache of nodes that might be referenced by readonly<> for de-duplication
    1357         std::unordered_map< BaseSyntaxNode *, ast::Node * > cache = {};
     1358        std::unordered_map< const BaseSyntaxNode *, ast::Node * > cache = {};
    13581359
    13591360        // Local Utilities:
     
    14221423                to<std::vector>::from( make_labels( std::move( labels ) ) )
    14231424
    1424         static ast::CV::Qualifiers cv( Type * ty ) { return { ty->get_qualifiers().val }; }
     1425        static ast::CV::Qualifiers cv( const Type * ty ) { return { ty->tq.val }; }
    14251426
    14261427        /// returns true and sets `node` if in cache
    1427         bool inCache( BaseSyntaxNode * old ) {
     1428        bool inCache( const BaseSyntaxNode * old ) {
    14281429                auto it = cache.find( old );
    14291430                if ( it == cache.end() ) return false;
     
    14341435        // Now all the visit functions:
    14351436
    1436         virtual void visit( ObjectDecl * old ) override final {
     1437        virtual void visit( const ObjectDecl * old ) override final {
    14371438                auto&& type = GET_ACCEPT_1(type, Type);
    14381439                auto&& init = GET_ACCEPT_1(init, Init);
     
    14651466        }
    14661467
    1467         virtual void visit( FunctionDecl * old ) override final {
     1468        virtual void visit( const FunctionDecl * old ) override final {
    14681469                if ( inCache( old ) ) return;
    14691470                auto decl = new ast::FunctionDecl{
     
    14981499        }
    14991500
    1500         virtual void visit( StructDecl * old ) override final {
     1501        virtual void visit( const StructDecl * old ) override final {
    15011502                if ( inCache( old ) ) return;
    15021503                auto decl = new ast::StructDecl(
     
    15231524        }
    15241525
    1525         virtual void visit( UnionDecl * old ) override final {
     1526        virtual void visit( const UnionDecl * old ) override final {
    15261527                if ( inCache( old ) ) return;
    15271528                auto decl = new ast::UnionDecl(
     
    15431544        }
    15441545
    1545         virtual void visit( EnumDecl * old ) override final {
     1546        virtual void visit( const EnumDecl * old ) override final {
    15461547                if ( inCache( old ) ) return;
    15471548                auto decl = new ast::EnumDecl(
     
    15631564        }
    15641565
    1565         virtual void visit( TraitDecl * old ) override final {
     1566        virtual void visit( const TraitDecl * old ) override final {
    15661567                if ( inCache( old ) ) return;
    15671568                auto decl = new ast::TraitDecl(
     
    15831584        }
    15841585
    1585         virtual void visit( TypeDecl * old ) override final {
     1586        virtual void visit( const TypeDecl * old ) override final {
    15861587                if ( inCache( old ) ) return;
    15871588                auto decl = new ast::TypeDecl{
     
    16031604        }
    16041605
    1605         virtual void visit( TypedefDecl * old ) override final {
     1606        virtual void visit( const TypedefDecl * old ) override final {
    16061607                auto decl = new ast::TypedefDecl(
    16071608                        old->location,
     
    16201621        }
    16211622
    1622         virtual void visit( AsmDecl * old ) override final {
     1623        virtual void visit( const AsmDecl * old ) override final {
    16231624                auto decl = new ast::AsmDecl{
    16241625                        old->location,
     
    16321633        }
    16331634
    1634         virtual void visit( StaticAssertDecl * old ) override final {
     1635        virtual void visit( const StaticAssertDecl * old ) override final {
    16351636                auto decl = new ast::StaticAssertDecl{
    16361637                        old->location,
     
    16451646        }
    16461647
    1647         virtual void visit( CompoundStmt * old ) override final {
     1648        virtual void visit( const CompoundStmt * old ) override final {
    16481649                if ( inCache( old ) ) return;
    16491650                auto stmt = new ast::CompoundStmt(
     
    16571658        }
    16581659
    1659         virtual void visit( ExprStmt * old ) override final {
     1660        virtual void visit( const ExprStmt * old ) override final {
    16601661                if ( inCache( old ) ) return;
    16611662                this->node = new ast::ExprStmt(
     
    16671668        }
    16681669
    1669         virtual void visit( AsmStmt * old ) override final {
     1670        virtual void visit( const AsmStmt * old ) override final {
    16701671                if ( inCache( old ) ) return;
    16711672                this->node = new ast::AsmStmt(
     
    16821683        }
    16831684
    1684         virtual void visit( DirectiveStmt * old ) override final {
     1685        virtual void visit( const DirectiveStmt * old ) override final {
    16851686                if ( inCache( old ) ) return;
    16861687                this->node = new ast::DirectiveStmt(
     
    16921693        }
    16931694
    1694         virtual void visit( IfStmt * old ) override final {
     1695        virtual void visit( const IfStmt * old ) override final {
    16951696                if ( inCache( old ) ) return;
    16961697                this->node = new ast::IfStmt(
     
    17051706        }
    17061707
    1707         virtual void visit( SwitchStmt * old ) override final {
     1708        virtual void visit( const SwitchStmt * old ) override final {
    17081709                if ( inCache( old ) ) return;
    17091710                this->node = new ast::SwitchStmt(
     
    17161717        }
    17171718
    1718         virtual void visit( CaseStmt * old ) override final {
     1719        virtual void visit( const CaseStmt * old ) override final {
    17191720                if ( inCache( old ) ) return;
    17201721                this->node = new ast::CaseStmt(
     
    17271728        }
    17281729
    1729         virtual void visit( WhileStmt * old ) override final {
     1730        virtual void visit( const WhileStmt * old ) override final {
    17301731                if ( inCache( old ) ) return;
    17311732                this->node = new ast::WhileStmt(
     
    17401741        }
    17411742
    1742         virtual void visit( ForStmt * old ) override final {
     1743        virtual void visit( const ForStmt * old ) override final {
    17431744                if ( inCache( old ) ) return;
    17441745                this->node = new ast::ForStmt(
     
    17531754        }
    17541755
    1755         virtual void visit( BranchStmt * old ) override final {
     1756        virtual void visit( const BranchStmt * old ) override final {
    17561757                if ( inCache( old ) ) return;
    17571758                if (old->computedTarget) {
     
    17901791        }
    17911792
    1792         virtual void visit( ReturnStmt * old ) override final {
     1793        virtual void visit( const ReturnStmt * old ) override final {
    17931794                if ( inCache( old ) ) return;
    17941795                this->node = new ast::ReturnStmt(
     
    18001801        }
    18011802
    1802         virtual void visit( ThrowStmt * old ) override final {
     1803        virtual void visit( const ThrowStmt * old ) override final {
    18031804                if ( inCache( old ) ) return;
    18041805                ast::ExceptionKind kind;
     
    18241825        }
    18251826
    1826         virtual void visit( TryStmt * old ) override final {
     1827        virtual void visit( const TryStmt * old ) override final {
    18271828                if ( inCache( old ) ) return;
    18281829                this->node = new ast::TryStmt(
     
    18361837        }
    18371838
    1838         virtual void visit( CatchStmt * old ) override final {
     1839        virtual void visit( const CatchStmt * old ) override final {
    18391840                if ( inCache( old ) ) return;
    18401841                ast::ExceptionKind kind;
     
    18611862        }
    18621863
    1863         virtual void visit( FinallyStmt * old ) override final {
     1864        virtual void visit( const FinallyStmt * old ) override final {
    18641865                if ( inCache( old ) ) return;
    18651866                this->node = new ast::FinallyStmt(
     
    18711872        }
    18721873
    1873         virtual void visit( WaitForStmt * old ) override final {
     1874        virtual void visit( const WaitForStmt * old ) override final {
    18741875                if ( inCache( old ) ) return;
    18751876                ast::WaitForStmt * stmt = new ast::WaitForStmt(
     
    19031904        }
    19041905
    1905         virtual void visit( WithStmt * old ) override final {
     1906        virtual void visit( const WithStmt * old ) override final {
    19061907                if ( inCache( old ) ) return;
    19071908                this->node = new ast::WithStmt(
    19081909                        old->location,
    19091910                        GET_ACCEPT_V(exprs, Expr),
    1910                         GET_ACCEPT_1(stmt, Stmt),
    1911                         GET_LABELS_V(old->labels)
     1911                        GET_ACCEPT_1(stmt, Stmt)
    19121912                );
    19131913                cache.emplace( old, this->node );
    19141914        }
    19151915
    1916         virtual void visit( NullStmt * old ) override final {
     1916        virtual void visit( const NullStmt * old ) override final {
    19171917                if ( inCache( old ) ) return;
    19181918                this->node = new ast::NullStmt(
     
    19231923        }
    19241924
    1925         virtual void visit( DeclStmt * old ) override final {
     1925        virtual void visit( const DeclStmt * old ) override final {
    19261926                if ( inCache( old ) ) return;
    19271927                this->node = new ast::DeclStmt(
     
    19331933        }
    19341934
    1935         virtual void visit( ImplicitCtorDtorStmt * old ) override final {
     1935        virtual void visit( const ImplicitCtorDtorStmt * old ) override final {
    19361936                if ( inCache( old ) ) return;
    19371937                auto stmt = new ast::ImplicitCtorDtorStmt(
     
    19901990        }
    19911991
    1992         ast::Expr * visitBaseExpr_SkipResultType(Expression * old, ast::Expr * nw) {
     1992        ast::Expr * visitBaseExpr_SkipResultType( const Expression * old, ast::Expr * nw) {
    19931993
    19941994                nw->env    = convertTypeSubstitution(old->env);
     
    20002000        }
    20012001
    2002         ast::Expr * visitBaseExpr(Expression * old, ast::Expr * nw) {
     2002        ast::Expr * visitBaseExpr( const Expression * old, ast::Expr * nw) {
    20032003
    20042004                nw->result = GET_ACCEPT_1(result, Type);
     
    20062006        }
    20072007
    2008         virtual void visit( ApplicationExpr * old ) override final {
     2008        virtual void visit( const ApplicationExpr * old ) override final {
    20092009                this->node = visitBaseExpr( old,
    20102010                        new ast::ApplicationExpr(
     
    20162016        }
    20172017
    2018         virtual void visit( UntypedExpr * old ) override final {
     2018        virtual void visit( const UntypedExpr * old ) override final {
    20192019                this->node = visitBaseExpr( old,
    20202020                        new ast::UntypedExpr(
     
    20262026        }
    20272027
    2028         virtual void visit( NameExpr * old ) override final {
     2028        virtual void visit( const NameExpr * old ) override final {
    20292029                this->node = visitBaseExpr( old,
    20302030                        new ast::NameExpr(
     
    20352035        }
    20362036
    2037         virtual void visit( CastExpr * old ) override final {
     2037        virtual void visit( const CastExpr * old ) override final {
    20382038                this->node = visitBaseExpr( old,
    20392039                        new ast::CastExpr(
     
    20452045        }
    20462046
    2047         virtual void visit( KeywordCastExpr * old) override final {
     2047        virtual void visit( const KeywordCastExpr * old) override final {
    20482048                ast::KeywordCastExpr::Target castTarget = ast::KeywordCastExpr::NUMBER_OF_TARGETS;
    20492049                switch (old->target) {
     
    20702070        }
    20712071
    2072         virtual void visit( VirtualCastExpr * old ) override final {
     2072        virtual void visit( const VirtualCastExpr * old ) override final {
    20732073                this->node = visitBaseExpr_SkipResultType( old,
    20742074                        new ast::VirtualCastExpr(
     
    20802080        }
    20812081
    2082         virtual void visit( AddressExpr * old ) override final {
     2082        virtual void visit( const AddressExpr * old ) override final {
    20832083                this->node = visitBaseExpr( old,
    20842084                        new ast::AddressExpr(
     
    20892089        }
    20902090
    2091         virtual void visit( LabelAddressExpr * old ) override final {
     2091        virtual void visit( const LabelAddressExpr * old ) override final {
    20922092                this->node = visitBaseExpr( old,
    20932093                        new ast::LabelAddressExpr(
     
    20982098        }
    20992099
    2100         virtual void visit( UntypedMemberExpr * old ) override final {
     2100        virtual void visit( const UntypedMemberExpr * old ) override final {
    21012101                this->node = visitBaseExpr( old,
    21022102                        new ast::UntypedMemberExpr(
     
    21082108        }
    21092109
    2110         virtual void visit( MemberExpr * old ) override final {
     2110        virtual void visit( const MemberExpr * old ) override final {
    21112111                this->node = visitBaseExpr( old,
    21122112                        new ast::MemberExpr(
     
    21182118        }
    21192119
    2120         virtual void visit( VariableExpr * old ) override final {
     2120        virtual void visit( const VariableExpr * old ) override final {
    21212121                auto expr = new ast::VariableExpr(
    21222122                        old->location
     
    21292129        }
    21302130
    2131         virtual void visit( ConstantExpr * old ) override final {
     2131        virtual void visit( const ConstantExpr * old ) override final {
    21322132                ast::ConstantExpr *rslt = new ast::ConstantExpr(
    21332133                        old->location,
    21342134                        GET_ACCEPT_1(result, Type),
    2135                         old->constant.get_value(),
     2135                        old->constant.rep,
    21362136                        old->constant.ival
    21372137                );
    2138                 rslt->underlyer = getAccept1< ast::Type, Type* >( old->constant.get_type() );
     2138                rslt->underlyer = getAccept1< ast::Type, Type* >( old->constant.type );
    21392139                this->node = visitBaseExpr( old, rslt );
    21402140        }
    21412141
    2142         virtual void visit( SizeofExpr * old ) override final {
     2142        virtual void visit( const SizeofExpr * old ) override final {
    21432143                assert (old->expr || old->type);
    21442144                assert (! (old->expr && old->type));
     
    21612161        }
    21622162
    2163         virtual void visit( AlignofExpr * old ) override final {
     2163        virtual void visit( const AlignofExpr * old ) override final {
    21642164                assert (old->expr || old->type);
    21652165                assert (! (old->expr && old->type));
     
    21822182        }
    21832183
    2184         virtual void visit( UntypedOffsetofExpr * old ) override final {
     2184        virtual void visit( const UntypedOffsetofExpr * old ) override final {
    21852185                this->node = visitBaseExpr( old,
    21862186                        new ast::UntypedOffsetofExpr(
     
    21922192        }
    21932193
    2194         virtual void visit( OffsetofExpr * old ) override final {
     2194        virtual void visit( const OffsetofExpr * old ) override final {
    21952195                this->node = visitBaseExpr( old,
    21962196                        new ast::OffsetofExpr(
     
    22022202        }
    22032203
    2204         virtual void visit( OffsetPackExpr * old ) override final {
     2204        virtual void visit( const OffsetPackExpr * old ) override final {
    22052205                this->node = visitBaseExpr( old,
    22062206                        new ast::OffsetPackExpr(
     
    22112211        }
    22122212
    2213         virtual void visit( LogicalExpr * old ) override final {
     2213        virtual void visit( const LogicalExpr * old ) override final {
    22142214                this->node = visitBaseExpr( old,
    22152215                        new ast::LogicalExpr(
     
    22242224        }
    22252225
    2226         virtual void visit( ConditionalExpr * old ) override final {
     2226        virtual void visit( const ConditionalExpr * old ) override final {
    22272227                this->node = visitBaseExpr( old,
    22282228                        new ast::ConditionalExpr(
     
    22352235        }
    22362236
    2237         virtual void visit( CommaExpr * old ) override final {
     2237        virtual void visit( const CommaExpr * old ) override final {
    22382238                this->node = visitBaseExpr( old,
    22392239                        new ast::CommaExpr(
     
    22452245        }
    22462246
    2247         virtual void visit( TypeExpr * old ) override final {
     2247        virtual void visit( const TypeExpr * old ) override final {
    22482248                this->node = visitBaseExpr( old,
    22492249                        new ast::TypeExpr(
     
    22542254        }
    22552255
    2256         virtual void visit( AsmExpr * old ) override final {
     2256        virtual void visit( const AsmExpr * old ) override final {
    22572257                this->node = visitBaseExpr( old,
    22582258                        new ast::AsmExpr(
     
    22652265        }
    22662266
    2267         virtual void visit( ImplicitCopyCtorExpr * old ) override final {
     2267        virtual void visit( const ImplicitCopyCtorExpr * old ) override final {
    22682268                auto rslt = new ast::ImplicitCopyCtorExpr(
    22692269                        old->location,
     
    22742274        }
    22752275
    2276         virtual void visit( ConstructorExpr * old ) override final {
     2276        virtual void visit( const ConstructorExpr * old ) override final {
    22772277                this->node = visitBaseExpr( old,
    22782278                        new ast::ConstructorExpr(
     
    22832283        }
    22842284
    2285         virtual void visit( CompoundLiteralExpr * old ) override final {
     2285        virtual void visit( const CompoundLiteralExpr * old ) override final {
    22862286                this->node = visitBaseExpr_SkipResultType( old,
    22872287                        new ast::CompoundLiteralExpr(
     
    22932293        }
    22942294
    2295         virtual void visit( RangeExpr * old ) override final {
     2295        virtual void visit( const RangeExpr * old ) override final {
    22962296                this->node = visitBaseExpr( old,
    22972297                        new ast::RangeExpr(
     
    23032303        }
    23042304
    2305         virtual void visit( UntypedTupleExpr * old ) override final {
     2305        virtual void visit( const UntypedTupleExpr * old ) override final {
    23062306                this->node = visitBaseExpr( old,
    23072307                        new ast::UntypedTupleExpr(
     
    23122312        }
    23132313
    2314         virtual void visit( TupleExpr * old ) override final {
     2314        virtual void visit( const TupleExpr * old ) override final {
    23152315                this->node = visitBaseExpr( old,
    23162316                        new ast::TupleExpr(
     
    23212321        }
    23222322
    2323         virtual void visit( TupleIndexExpr * old ) override final {
     2323        virtual void visit( const TupleIndexExpr * old ) override final {
    23242324                this->node = visitBaseExpr( old,
    23252325                        new ast::TupleIndexExpr(
     
    23312331        }
    23322332
    2333         virtual void visit( TupleAssignExpr * old ) override final {
     2333        virtual void visit( const TupleAssignExpr * old ) override final {
    23342334                this->node = visitBaseExpr_SkipResultType( old,
    23352335                        new ast::TupleAssignExpr(
     
    23412341        }
    23422342
    2343         virtual void visit( StmtExpr * old ) override final {
     2343        virtual void visit( const StmtExpr * old ) override final {
    23442344                auto rslt = new ast::StmtExpr(
    23452345                        old->location,
     
    23522352        }
    23532353
    2354         virtual void visit( UniqueExpr * old ) override final {
     2354        virtual void visit( const UniqueExpr * old ) override final {
    23552355                auto rslt = new ast::UniqueExpr(
    23562356                        old->location,
     
    23642364        }
    23652365
    2366         virtual void visit( UntypedInitExpr * old ) override final {
     2366        virtual void visit( const UntypedInitExpr * old ) override final {
    23672367                std::deque<ast::InitAlternative> initAlts;
    23682368                for (auto ia : old->initAlts) {
     
    23812381        }
    23822382
    2383         virtual void visit( InitExpr * old ) override final {
     2383        virtual void visit( const InitExpr * old ) override final {
    23842384                this->node = visitBaseExpr( old,
    23852385                        new ast::InitExpr(
     
    23912391        }
    23922392
    2393         virtual void visit( DeletedExpr * old ) override final {
     2393        virtual void visit( const DeletedExpr * old ) override final {
    23942394                this->node = visitBaseExpr( old,
    23952395                        new ast::DeletedExpr(
     
    23972397                                GET_ACCEPT_1(expr, Expr),
    23982398                                inCache(old->deleteStmt) ?
    2399                                         this->node :
    2400                                         GET_ACCEPT_1(deleteStmt, Node)
    2401                         )
    2402                 );
    2403         }
    2404 
    2405         virtual void visit( DefaultArgExpr * old ) override final {
     2399                                        strict_dynamic_cast<ast::Decl*>(this->node) :
     2400                                        GET_ACCEPT_1(deleteStmt, Decl)
     2401                        )
     2402                );
     2403        }
     2404
     2405        virtual void visit( const DefaultArgExpr * old ) override final {
    24062406                this->node = visitBaseExpr( old,
    24072407                        new ast::DefaultArgExpr(
     
    24122412        }
    24132413
    2414         virtual void visit( GenericExpr * old ) override final {
     2414        virtual void visit( const GenericExpr * old ) override final {
    24152415                std::vector<ast::GenericExpr::Association> associations;
    24162416                for (auto association : old->associations) {
     
    24292429        }
    24302430
    2431         void visitType( Type * old, ast::Type * type ) {
     2431        void visitType( const Type * old, ast::Type * type ) {
    24322432                // Some types do this in their constructor so add a check.
    24332433                if ( !old->attributes.empty() && type->attributes.empty() ) {
     
    24372437        }
    24382438
    2439         virtual void visit( VoidType * old ) override final {
     2439        virtual void visit( const VoidType * old ) override final {
    24402440                visitType( old, new ast::VoidType{ cv( old ) } );
    24412441        }
    24422442
    2443         virtual void visit( BasicType * old ) override final {
     2443        virtual void visit( const BasicType * old ) override final {
    24442444                auto type = new ast::BasicType{ (ast::BasicType::Kind)(unsigned)old->kind, cv( old ) };
    24452445                // I believe this should always be a BasicType.
     
    24502450        }
    24512451
    2452         virtual void visit( PointerType * old ) override final {
     2452        virtual void visit( const PointerType * old ) override final {
    24532453                visitType( old, new ast::PointerType{
    24542454                        GET_ACCEPT_1( base, Type ),
     
    24602460        }
    24612461
    2462         virtual void visit( ArrayType * old ) override final {
     2462        virtual void visit( const ArrayType * old ) override final {
    24632463                visitType( old, new ast::ArrayType{
    24642464                        GET_ACCEPT_1( base, Type ),
     
    24702470        }
    24712471
    2472         virtual void visit( ReferenceType * old ) override final {
     2472        virtual void visit( const ReferenceType * old ) override final {
    24732473                visitType( old, new ast::ReferenceType{
    24742474                        GET_ACCEPT_1( base, Type ),
     
    24772477        }
    24782478
    2479         virtual void visit( QualifiedType * old ) override final {
     2479        virtual void visit( const QualifiedType * old ) override final {
    24802480                visitType( old, new ast::QualifiedType{
    24812481                        GET_ACCEPT_1( parent, Type ),
     
    24852485        }
    24862486
    2487         virtual void visit( FunctionType * old ) override final {
     2487        virtual void visit( const FunctionType * old ) override final {
    24882488                auto ty = new ast::FunctionType {
    24892489                        (ast::ArgumentFlag)old->isVarArgs,
     
    24962496        }
    24972497
    2498         void postvisit( ReferenceToType * old, ast::ReferenceToType * ty ) {
     2498        void postvisit( const ReferenceToType * old, ast::ReferenceToType * ty ) {
    24992499                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
    25002500                ty->params = GET_ACCEPT_V( parameters, Expr );
     
    25032503        }
    25042504
    2505         virtual void visit( StructInstType * old ) override final {
     2505        virtual void visit( const StructInstType * old ) override final {
    25062506                ast::StructInstType * ty;
    25072507                if ( old->baseStruct ) {
     
    25212521        }
    25222522
    2523         virtual void visit( UnionInstType * old ) override final {
     2523        virtual void visit( const UnionInstType * old ) override final {
    25242524                ast::UnionInstType * ty;
    25252525                if ( old->baseUnion ) {
     
    25392539        }
    25402540
    2541         virtual void visit( EnumInstType * old ) override final {
     2541        virtual void visit( const EnumInstType * old ) override final {
    25422542                ast::EnumInstType * ty;
    25432543                if ( old->baseEnum ) {
     
    25572557        }
    25582558
    2559         virtual void visit( TraitInstType * old ) override final {
     2559        virtual void visit( const TraitInstType * old ) override final {
    25602560                ast::TraitInstType * ty;
    25612561                if ( old->baseTrait ) {
     
    25752575        }
    25762576
    2577         virtual void visit( TypeInstType * old ) override final {
     2577        virtual void visit( const TypeInstType * old ) override final {
    25782578                ast::TypeInstType * ty;
    25792579                if ( old->baseType ) {
     
    25952595        }
    25962596
    2597         virtual void visit( TupleType * old ) override final {
     2597        virtual void visit( const TupleType * old ) override final {
    25982598                visitType( old, new ast::TupleType{
    25992599                        GET_ACCEPT_V( types, Type ),
     
    26032603        }
    26042604
    2605         virtual void visit( TypeofType * old ) override final {
     2605        virtual void visit( const TypeofType * old ) override final {
    26062606                visitType( old, new ast::TypeofType{
    26072607                        GET_ACCEPT_1( expr, Expr ),
     
    26112611        }
    26122612
    2613         virtual void visit( AttrType * ) override final {
     2613        virtual void visit( const AttrType * ) override final {
    26142614                assertf( false, "AttrType deprecated in new AST." );
    26152615        }
    26162616
    2617         virtual void visit( VarArgsType * old ) override final {
     2617        virtual void visit( const VarArgsType * old ) override final {
    26182618                visitType( old, new ast::VarArgsType{ cv( old ) } );
    26192619        }
    26202620
    2621         virtual void visit( ZeroType * old ) override final {
     2621        virtual void visit( const ZeroType * old ) override final {
    26222622                visitType( old, new ast::ZeroType{ cv( old ) } );
    26232623        }
    26242624
    2625         virtual void visit( OneType * old ) override final {
     2625        virtual void visit( const OneType * old ) override final {
    26262626                visitType( old, new ast::OneType{ cv( old ) } );
    26272627        }
    26282628
    2629         virtual void visit( GlobalScopeType * old ) override final {
     2629        virtual void visit( const GlobalScopeType * old ) override final {
    26302630                visitType( old, new ast::GlobalScopeType{} );
    26312631        }
    26322632
    2633         virtual void visit( Designation * old ) override final {
     2633        virtual void visit( const Designation * old ) override final {
    26342634                this->node = new ast::Designation(
    26352635                        old->location,
     
    26382638        }
    26392639
    2640         virtual void visit( SingleInit * old ) override final {
     2640        virtual void visit( const SingleInit * old ) override final {
    26412641                this->node = new ast::SingleInit(
    26422642                        old->location,
     
    26462646        }
    26472647
    2648         virtual void visit( ListInit * old ) override final {
     2648        virtual void visit( const ListInit * old ) override final {
    26492649                this->node = new ast::ListInit(
    26502650                        old->location,
     
    26552655        }
    26562656
    2657         virtual void visit( ConstructorInit * old ) override final {
     2657        virtual void visit( const ConstructorInit * old ) override final {
    26582658                this->node = new ast::ConstructorInit(
    26592659                        old->location,
     
    26642664        }
    26652665
    2666         virtual void visit( Constant * ) override final {
     2666        virtual void visit( const Constant * ) override final {
    26672667                // Handled in visit( ConstantEpxr * ).
    26682668                // In the new tree, Constant fields are inlined into containing ConstantExpression.
     
    26702670        }
    26712671
    2672         virtual void visit( Attribute * old ) override final {
     2672        virtual void visit( const Attribute * old ) override final {
    26732673                this->node = new ast::Attribute(
    26742674                        old->name,
     
    26772677        }
    26782678
    2679         virtual void visit( AttrExpr * ) override final {
     2679        virtual void visit( const AttrExpr * ) override final {
    26802680                assertf( false, "AttrExpr deprecated in new AST." );
    26812681        }
  • src/AST/Decl.hpp

    r1f1c102 rf53acdf8  
    102102        ptr<Expr> bitfieldWidth;
    103103
    104         ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type, 
    105                 const Init * init = nullptr, Storage::Classes storage = {}, 
    106                 Linkage::Spec linkage = Linkage::C, const Expr * bitWd = nullptr, 
     104        ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type,
     105                const Init * init = nullptr, Storage::Classes storage = {},
     106                Linkage::Spec linkage = Linkage::C, const Expr * bitWd = nullptr,
    107107                std::vector< ptr<Attribute> > && attrs = {}, Function::Specs fs = {} )
    108108        : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ),
     
    323323};
    324324
     325/// With statement `with (...) ...`
     326class WithStmt final : public Decl {
     327public:
     328        std::vector<ptr<Expr>> exprs;
     329        ptr<Stmt> stmt;
     330
     331        WithStmt( const CodeLocation & loc, std::vector<ptr<Expr>> && exprs, const Stmt * stmt )
     332        : Decl(loc, "", Storage::Auto, Linkage::Cforall), exprs(std::move(exprs)), stmt(stmt) {}
     333
     334        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
     335private:
     336        WithStmt * clone() const override { return new WithStmt{ *this }; }
     337        MUTATE_FRIEND
     338};
     339
    325340class AsmDecl : public Decl {
    326341public:
  • src/AST/Expr.hpp

    r1f1c102 rf53acdf8  
    4747
    4848        ParamEntry() : decl( 0 ), declptr( nullptr ), actualType( nullptr ), formalType( nullptr ), expr( nullptr ) {}
    49         ParamEntry( 
    50                 UniqueId id, const Decl * declptr, const Type * actual, const Type * formal, 
     49        ParamEntry(
     50                UniqueId id, const Decl * declptr, const Type * actual, const Type * formal,
    5151                const Expr * e )
    5252        : decl( id ), declptr( declptr ), actualType( actual ), formalType( formal ), expr( e ) {}
     
    112112                        case Empty: new(&data.resnSlots) ResnSlots{}; mode = Slots; // fallthrough
    113113                        case Slots: return data.resnSlots;
    114                         case Params: assert(!"Cannot return to resnSlots from Params");
     114                        case Params: assertf(false, "Cannot return to resnSlots from Params"); abort();
    115115                        }
    116                         return *((ResnSlots*)nullptr);
     116                        assertf(false, "unreachable");
    117117                }
    118118
     
    121121                                return data.resnSlots;
    122122                        }
    123                         assert(!"Mode was not already resnSlots");
    124                         return *((ResnSlots*)nullptr);
     123                        assertf(false, "Mode was not already resnSlots");
     124                        abort();
    125125                }
    126126
     
    131131                        case Params: return data.inferParams;
    132132                        }
    133                         assert(!"unreachable");
    134                         return *((InferredParams*)nullptr);
     133                        assertf(false, "unreachable");
    135134                }
    136135
     
    139138                                return data.inferParams;
    140139                        }
    141                         assert(!"Mode was not already Params");
    142                         return *((InferredParams*)nullptr);
     140                        assertf(false, "Mode was not already Params");
     141                        abort();
    143142                }
    144143
    145144                void set_inferParams( InferredParams && ps ) {
    146145                        switch(mode) {
    147                         case Slots: 
     146                        case Slots:
    148147                                data.resnSlots.~ResnSlots();
    149148                                // fallthrough
    150                         case Empty: 
     149                        case Empty:
    151150                                new(&data.inferParams) InferredParams{ std::move( ps ) };
    152151                                mode = Params;
     
    172171                                        data.inferParams[p.first] = std::move(p.second);
    173172                                }
    174                         } else assert(!"invalid mode");
     173                        } else assertf(false, "invalid mode");
    175174                }
    176175        };
     
    384383
    385384        ConstantExpr(
    386                 const CodeLocation & loc, const Type * ty, const std::string & r, 
     385                const CodeLocation & loc, const Type * ty, const std::string & r,
    387386                        std::optional<unsigned long long> i )
    388387        : Expr( loc, ty ), rep( r ), ival( i ) {}
     
    770769public:
    771770        ptr<Expr> expr;
    772         readonly<Node> deleteStmt;
    773 
    774         DeletedExpr( const CodeLocation & loc, const Expr * e, const Node * del )
     771        readonly<Decl> deleteStmt;
     772
     773        DeletedExpr( const CodeLocation & loc, const Expr * e, const Decl * del )
    775774        : Expr( loc, e->result ), expr( e ), deleteStmt( del ) { assert( expr->result ); }
    776775
  • src/AST/Pass.hpp

    r1f1c102 rf53acdf8  
    115115        const ast::Stmt *             visit( const ast::FinallyStmt          * ) override final;
    116116        const ast::Stmt *             visit( const ast::WaitForStmt          * ) override final;
    117         const ast::Stmt *             visit( const ast::WithStmt             * ) override final;
     117        const ast::Decl *             visit( const ast::WithStmt             * ) override final;
    118118        const ast::NullStmt *         visit( const ast::NullStmt             * ) override final;
    119119        const ast::Stmt *             visit( const ast::DeclStmt             * ) override final;
  • src/AST/Pass.impl.hpp

    r1f1c102 rf53acdf8  
    909909// WithStmt
    910910template< typename pass_t >
    911 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::WithStmt * node ) {
     911const ast::Decl * ast::Pass< pass_t >::visit( const ast::WithStmt * node ) {
    912912        VISIT_START( node );
    913913
  • src/AST/Print.cpp

    r1f1c102 rf53acdf8  
    3737}
    3838
    39 class Printer : public Visitor {
     39class Printer final : public Visitor {
    4040public:
    4141        ostream & os;
     
    272272
    273273public:
    274         virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) {
     274        virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final {
    275275                if ( ! node->name.empty() ) os << node->name << ": ";
    276276
     
    314314        }
    315315
    316         virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) {
     316        virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final {
    317317                if ( !node->name.empty() ) os << node->name << ": ";
    318318
     
    342342        }
    343343
    344         virtual const ast::Decl * visit( const ast::StructDecl * node ) {
     344        virtual const ast::Decl * visit( const ast::StructDecl * node ) override final {
    345345                print(node);
    346346                return node;
    347347        }
    348348
    349         virtual const ast::Decl * visit( const ast::UnionDecl * node ) {
     349        virtual const ast::Decl * visit( const ast::UnionDecl * node ) override final {
    350350                print(node);
    351351                return node;
    352352        }
    353353
    354         virtual const ast::Decl * visit( const ast::EnumDecl * node ) {
     354        virtual const ast::Decl * visit( const ast::EnumDecl * node ) override final {
    355355                print(node);
    356356                return node;
    357357        }
    358358
    359         virtual const ast::Decl * visit( const ast::TraitDecl * node ) {
     359        virtual const ast::Decl * visit( const ast::TraitDecl * node ) override final {
    360360                print(node);
    361361                return node;
    362362        }
    363363
    364         virtual const ast::Decl * visit( const ast::TypeDecl * node ) {
     364        virtual const ast::Decl * visit( const ast::TypeDecl * node ) override final {
    365365                preprint( node );
    366366                if ( ! short_mode && node->init ) {
     
    374374        }
    375375
    376         virtual const ast::Decl * visit( const ast::TypedefDecl * node ) {
    377                 preprint( node );
    378                 return node;
    379         }
    380 
    381         virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) {
     376        virtual const ast::Decl * visit( const ast::TypedefDecl * node ) override final {
     377                preprint( node );
     378                return node;
     379        }
     380
     381        virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final {
    382382                safe_print( node->stmt );
    383383                return node;
    384384        }
    385385
    386         virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) {
     386        virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) override final {
    387387                os << "Static Assert with condition: ";
    388388                ++indent;
     
    396396        }
    397397
    398         virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) {
     398        virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final {
    399399                os << "Compound Statement:" << endl;
    400400                ++indent;
     
    404404        }
    405405
    406         virtual const ast::Stmt * visit( const ast::ExprStmt * node ) {
     406        virtual const ast::Stmt * visit( const ast::ExprStmt * node ) override final {
    407407                ++indent;
    408408                os << "Expression Statement:" << endl << indent;
     
    412412        }
    413413
    414         virtual const ast::Stmt * visit( const ast::AsmStmt * node ) {
     414        virtual const ast::Stmt * visit( const ast::AsmStmt * node ) override final {
    415415                os << "Assembler Statement:" << endl;
    416416                ++indent;
     
    433433        }
    434434
    435         virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) {
     435        virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) override final {
    436436                os << "GCC Directive: " << node->directive << endl;
    437437                return node;
    438438        }
    439439
    440         virtual const ast::Stmt * visit( const ast::IfStmt * node ) {
     440        virtual const ast::Stmt * visit( const ast::IfStmt * node ) override final {
    441441                os << "If on condition:" << endl;
    442442                ++indent;
     
    473473        }
    474474
    475         virtual const ast::Stmt * visit( const ast::WhileStmt * node ) {
     475        virtual const ast::Stmt * visit( const ast::WhileStmt * node ) override final {
    476476                if ( node->isDoWhile ) { os << "Do-"; }
    477477                os << "While on condition:" << endl;
     
    490490        }
    491491
    492         virtual const ast::Stmt * visit( const ast::ForStmt * node ) {
     492        virtual const ast::Stmt * visit( const ast::ForStmt * node ) override final {
    493493                os << "For Statement" << endl;
    494494
     
    532532        }
    533533
    534         virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) {
     534        virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) override final {
    535535                os << "Switch on condition: ";
    536536                safe_print( node->cond );
     
    546546        }
    547547
    548         virtual const ast::Stmt * visit( const ast::CaseStmt * node ) {
     548        virtual const ast::Stmt * visit( const ast::CaseStmt * node ) override final {
    549549                if ( node->isDefault() ) {
    550550                        os << indent << "Default ";
     
    565565        }
    566566
    567         virtual const ast::Stmt * visit( const ast::BranchStmt * node ) {
     567        virtual const ast::Stmt * visit( const ast::BranchStmt * node ) override final {
    568568                os << "Branch (" << node->kindName() << ")" << endl;
    569569                ++indent;
     
    586586        }
    587587
    588         virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) {
     588        virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) override final {
    589589                os << "Return Statement, returning";
    590590                if ( node->expr ) {
     
    601601        }
    602602
    603         virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) {
     603        virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) override final {
    604604                if ( node->target ) os << "Non-Local ";
    605605
     
    621621        }
    622622
    623         virtual const ast::Stmt * visit( const ast::TryStmt * node ) {
     623        virtual const ast::Stmt * visit( const ast::TryStmt * node ) override final {
    624624                ++indent;
    625625                os << "Try Statement" << endl << indent-1
     
    642642        }
    643643
    644         virtual const ast::Stmt * visit( const ast::CatchStmt * node ) {
     644        virtual const ast::Stmt * visit( const ast::CatchStmt * node ) override final {
    645645                os << "Catch ";
    646646                switch ( node->kind ) {
     
    667667        }
    668668
    669         virtual const ast::Stmt * visit( const ast::FinallyStmt * node ) {
     669        virtual const ast::Stmt * visit( const ast::FinallyStmt * node ) override final {
    670670                os << "Finally Statement" << endl;
    671671                os << indent << "... with block:" << endl;
     
    678678        }
    679679
    680         virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) {
     680        virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) override final {
    681681                os << "Waitfor Statement" << endl;
    682682                indent += 2;
     
    732732        }
    733733
    734         virtual const ast::Stmt * visit( const ast::WithStmt * node ) {
     734        virtual const ast::Decl * visit( const ast::WithStmt * node ) override final {
    735735                os << "With statement" << endl;
    736736                os << indent << "... with expressions:" << endl;
     
    744744        }
    745745
    746         virtual const ast::NullStmt * visit( const ast::NullStmt * node ) {
     746        virtual const ast::NullStmt * visit( const ast::NullStmt * node ) override final {
    747747                os << "Null Statement" << endl;
    748748                print( node->labels );
     
    751751        }
    752752
    753         virtual const ast::Stmt * visit( const ast::DeclStmt * node ) {
     753        virtual const ast::Stmt * visit( const ast::DeclStmt * node ) override final {
    754754                os << "Declaration of ";
    755755                safe_print( node->decl );
     
    758758        }
    759759
    760         virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) {
     760        virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) override final {
    761761                os << "Implicit Ctor Dtor Statement" << endl;
    762762                os << indent << "... with Ctor/Dtor: ";
     
    769769        }
    770770
    771         virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) {
     771        virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) override final {
    772772                ++indent;
    773773                os << "Application of" << endl << indent;
     
    784784        }
    785785
    786         virtual const ast::Expr * visit( const ast::UntypedExpr * node ) {
     786        virtual const ast::Expr * visit( const ast::UntypedExpr * node ) override final {
    787787                ++indent;
    788788                os << "Applying untyped:" << endl;
     
    797797        }
    798798
    799         virtual const ast::Expr * visit( const ast::NameExpr * node ) {
     799        virtual const ast::Expr * visit( const ast::NameExpr * node ) override final {
    800800                os << "Name: " << node->name;
    801801                postprint( node );
     
    804804        }
    805805
    806         virtual const ast::Expr * visit( const ast::AddressExpr * node ) {
     806        virtual const ast::Expr * visit( const ast::AddressExpr * node ) override final {
    807807                os << "Address of:" << endl;
    808808                ++indent;
     
    815815        }
    816816
    817         virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) {
     817        virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) override final {
    818818                os << "Address of label:" << node->arg;
    819819
     
    821821        }
    822822
    823         virtual const ast::Expr * visit( const ast::CastExpr * node ) {
     823        virtual const ast::Expr * visit( const ast::CastExpr * node ) override final {
    824824                ++indent;
    825825                os << (node->isGenerated ? "Generated" : "Explicit") << " cast of:" << endl << indent;
     
    841841        }
    842842
    843         virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) {
     843        virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final {
    844844                ++indent;
    845845                os << "Keyword Cast of:" << endl << indent;
     
    852852        }
    853853
    854         virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) {
     854        virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) override final {
    855855                ++indent;
    856856                os << "Virtual Cast of:" << endl << indent;
     
    869869        }
    870870
    871         virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) {
     871        virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) override final {
    872872                ++indent;
    873873                os << "Untyped Member Expression, with field: " << endl << indent;
     
    881881        }
    882882
    883         virtual const ast::Expr * visit( const ast::MemberExpr * node ) {
     883        virtual const ast::Expr * visit( const ast::MemberExpr * node ) override final {
    884884                ++indent;
    885885                os << "Member Expression, with field:" << endl << indent;
     
    893893        }
    894894
    895         virtual const ast::Expr * visit( const ast::VariableExpr * node ) {
     895        virtual const ast::Expr * visit( const ast::VariableExpr * node ) override final {
    896896                os << "Variable Expression: ";
    897897                short_print( node->var );
     
    901901        }
    902902
    903         virtual const ast::Expr * visit( const ast::ConstantExpr * node ) {
     903        virtual const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
    904904                os << "Constant Expression (" << node->rep;
    905905                if ( node->result ) {
     
    913913        }
    914914
    915         virtual const ast::Expr * visit( const ast::SizeofExpr * node ) {
     915        virtual const ast::Expr * visit( const ast::SizeofExpr * node ) override final {
    916916                os << "Sizeof Expression on: ";
    917917                ++indent;
     
    924924        }
    925925
    926         virtual const ast::Expr * visit( const ast::AlignofExpr * node ) {
     926        virtual const ast::Expr * visit( const ast::AlignofExpr * node ) override final {
    927927                os << "Alignof Expression on: ";
    928928                ++indent;
     
    935935        }
    936936
    937         virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) {
     937        virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) override final {
    938938                os << "Untyped Offsetof Expression on member " << node->member << " of ";
    939939                ++indent;
     
    945945        }
    946946
    947         virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) {
     947        virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) override final {
    948948                os << "Offsetof Expression on member " << node->member->name << " of ";
    949949                ++indent;
     
    955955        }
    956956
    957         virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) {
     957        virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) override final {
    958958                os << "Offset Pack Expression on: ";
    959959                ++indent;
     
    965965        }
    966966
    967         virtual const ast::Expr * visit( const ast::LogicalExpr * node ) {
     967        virtual const ast::Expr * visit( const ast::LogicalExpr * node ) override final {
    968968                os << "Short-circuited operation (" << (node->isAnd ? "and" : "or") << ") on: ";
    969969                safe_print( node->arg1 );
     
    975975        }
    976976
    977         virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) {
     977        virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) override final {
    978978                ++indent;
    979979                os << "Conditional expression on:" << endl << indent;
     
    989989        }
    990990
    991         virtual const ast::Expr * visit( const ast::CommaExpr * node ) {
     991        virtual const ast::Expr * visit( const ast::CommaExpr * node ) override final {
    992992                ++indent;
    993993                os << "Comma Expression:" << endl << indent;
     
    10011001        }
    10021002
    1003         virtual const ast::Expr * visit( const ast::TypeExpr * node ) {
     1003        virtual const ast::Expr * visit( const ast::TypeExpr * node ) override final {
    10041004                safe_print( node->type );
    10051005                postprint( node );
     
    10081008        }
    10091009
    1010         virtual const ast::Expr * visit( const ast::AsmExpr * node ) {
     1010        virtual const ast::Expr * visit( const ast::AsmExpr * node ) override final {
    10111011                os << "Asm Expression:" << endl;
    10121012                ++indent;
     
    10191019        }
    10201020
    1021         virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) {
     1021        virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) override final {
    10221022                ++indent;
    10231023                os << "Implicit Copy Constructor Expression:" << endl << indent;
     
    10291029        }
    10301030
    1031         virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) {
     1031        virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) override final {
    10321032                os <<  "Constructor Expression:" << endl << indent+1;
    10331033                indent += 2;
     
    10391039        }
    10401040
    1041         virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) {
     1041        virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) override final {
    10421042                ++indent;
    10431043                os << "Compound Literal Expression: " << endl << indent;
     
    10511051        }
    10521052
    1053         virtual const ast::Expr * visit( const ast::RangeExpr * node ) {
     1053        virtual const ast::Expr * visit( const ast::RangeExpr * node ) override final {
    10541054                os << "Range Expression: ";
    10551055                safe_print( node->low );
     
    10611061        }
    10621062
    1063         virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) {
     1063        virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) override final {
    10641064                os << "Untyped Tuple:" << endl;
    10651065                ++indent;
     
    10711071        }
    10721072
    1073         virtual const ast::Expr * visit( const ast::TupleExpr * node ) {
     1073        virtual const ast::Expr * visit( const ast::TupleExpr * node ) override final {
    10741074                os << "Tuple:" << endl;
    10751075                ++indent;
     
    10811081        }
    10821082
    1083         virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) {
     1083        virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) override final {
    10841084                os << "Tuple Index Expression, with tuple:" << endl;
    10851085                ++indent;
     
    10931093        }
    10941094
    1095         virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) {
     1095        virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) override final {
    10961096                os << "Tuple Assignment Expression, with stmt expr:" << endl;
    10971097                ++indent;
     
    11041104        }
    11051105
    1106         virtual const ast::Expr * visit( const ast::StmtExpr * node ) {
     1106        virtual const ast::Expr * visit( const ast::StmtExpr * node ) override final {
    11071107                ++indent;
    11081108                os << "Statement Expression:" << endl << indent;
     
    11221122        }
    11231123
    1124         virtual const ast::Expr * visit( const ast::UniqueExpr * node ) {
     1124        virtual const ast::Expr * visit( const ast::UniqueExpr * node ) override final {
    11251125                ++indent;
    11261126                os << "Unique Expression with id: " << node->id << endl << indent;
     
    11361136        }
    11371137
    1138         virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) {
     1138        virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) override final {
    11391139                ++indent;
    11401140                os << "Untyped Init Expression" << endl << indent;
     
    11521152        }
    11531153
    1154         virtual const ast::Expr * visit( const ast::InitExpr * node ) {
     1154        virtual const ast::Expr * visit( const ast::InitExpr * node ) override final {
    11551155                ++indent;
    11561156                os << "Init Expression" << endl << indent;
     
    11631163        }
    11641164
    1165         virtual const ast::Expr * visit( const ast::DeletedExpr * node ) {
     1165        virtual const ast::Expr * visit( const ast::DeletedExpr * node ) override final {
    11661166                ++indent;
    11671167                os << "Deleted Expression" << endl << indent;
     
    11741174        }
    11751175
    1176         virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) {
     1176        virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) override final {
    11771177                ++indent;
    11781178                os << "Default Argument Expression" << endl << indent;
     
    11831183        }
    11841184
    1185         virtual const ast::Expr * visit( const ast::GenericExpr * node ) {
     1185        virtual const ast::Expr * visit( const ast::GenericExpr * node ) override final {
    11861186                ++indent;
    11871187                os << "C11 _Generic Expression" << endl << indent;
     
    12061206        }
    12071207
    1208         virtual const ast::Type * visit( const ast::VoidType * node ) {
     1208        virtual const ast::Type * visit( const ast::VoidType * node ) override final {
    12091209                preprint( node );
    12101210                os << "void";
     
    12121212        }
    12131213
    1214         virtual const ast::Type * visit( const ast::BasicType * node ) {
     1214        virtual const ast::Type * visit( const ast::BasicType * node ) override final {
    12151215                preprint( node );
    12161216                os << ast::BasicType::typeNames[ node->kind ];
     
    12181218        }
    12191219
    1220         virtual const ast::Type * visit( const ast::PointerType * node ) {
     1220        virtual const ast::Type * visit( const ast::PointerType * node ) override final {
    12211221                preprint( node );
    12221222                if ( ! node->isArray() ) {
     
    12411241        }
    12421242
    1243         virtual const ast::Type * visit( const ast::ArrayType * node ) {
     1243        virtual const ast::Type * visit( const ast::ArrayType * node ) override final {
    12441244                preprint( node );
    12451245                if ( node->isStatic ) {
     
    12651265        }
    12661266
    1267         virtual const ast::Type * visit( const ast::ReferenceType * node ) {
     1267        virtual const ast::Type * visit( const ast::ReferenceType * node ) override final {
    12681268                preprint( node );
    12691269                os << "reference to ";
     
    12731273        }
    12741274
    1275         virtual const ast::Type * visit( const ast::QualifiedType * node ) {
     1275        virtual const ast::Type * visit( const ast::QualifiedType * node ) override final {
    12761276                preprint( node );
    12771277                ++indent;
     
    12861286        }
    12871287
    1288         virtual const ast::Type * visit( const ast::FunctionType * node ) {
     1288        virtual const ast::Type * visit( const ast::FunctionType * node ) override final {
    12891289                preprint( node );
    12901290
     
    13151315        }
    13161316
    1317         virtual const ast::Type * visit( const ast::StructInstType * node ) {
     1317        virtual const ast::Type * visit( const ast::StructInstType * node ) override final {
    13181318                preprint( node );
    13191319                os << "instance of struct " << node->name;
     
    13261326        }
    13271327
    1328         virtual const ast::Type * visit( const ast::UnionInstType * node ) {
     1328        virtual const ast::Type * visit( const ast::UnionInstType * node ) override final {
    13291329                preprint( node );
    13301330                os << "instance of union " << node->name;
     
    13371337        }
    13381338
    1339         virtual const ast::Type * visit( const ast::EnumInstType * node ) {
     1339        virtual const ast::Type * visit( const ast::EnumInstType * node ) override final {
    13401340                preprint( node );
    13411341                os << "instance of enum " << node->name;
     
    13481348        }
    13491349
    1350         virtual const ast::Type * visit( const ast::TraitInstType * node ) {
     1350        virtual const ast::Type * visit( const ast::TraitInstType * node ) override final {
    13511351                preprint( node );
    13521352                os << "instance of trait " << node->name;
     
    13561356        }
    13571357
    1358         virtual const ast::Type * visit( const ast::TypeInstType * node ) {
     1358        virtual const ast::Type * visit( const ast::TypeInstType * node ) override final {
    13591359                preprint( node );
    13601360                os << "instance of type " << node->name
     
    13651365        }
    13661366
    1367         virtual const ast::Type * visit( const ast::TupleType * node ) {
     1367        virtual const ast::Type * visit( const ast::TupleType * node ) override final {
    13681368                preprint( node );
    13691369                os << "tuple of types" << endl;
     
    13751375        }
    13761376
    1377         virtual const ast::Type * visit( const ast::TypeofType * node ) {
     1377        virtual const ast::Type * visit( const ast::TypeofType * node ) override final {
    13781378                preprint( node );
    13791379                if ( node->kind == ast::TypeofType::Basetypeof ) { os << "base-"; }
     
    13841384        }
    13851385
    1386         virtual const ast::Type * visit( const ast::VarArgsType * node ) {
     1386        virtual const ast::Type * visit( const ast::VarArgsType * node ) override final {
    13871387                preprint( node );
    13881388                os << "builtin var args pack";
     
    13901390        }
    13911391
    1392         virtual const ast::Type * visit( const ast::ZeroType * node ) {
     1392        virtual const ast::Type * visit( const ast::ZeroType * node ) override final {
    13931393                preprint( node );
    13941394                os << "zero_t";
     
    13961396        }
    13971397
    1398         virtual const ast::Type * visit( const ast::OneType * node ) {
     1398        virtual const ast::Type * visit( const ast::OneType * node ) override final {
    13991399                preprint( node );
    14001400                os << "one_t";
     
    14021402        }
    14031403
    1404         virtual const ast::Type * visit( const ast::GlobalScopeType * node ) {
     1404        virtual const ast::Type * visit( const ast::GlobalScopeType * node ) override final {
    14051405                preprint( node );
    14061406                os << "Global Scope Type";
     
    14081408        }
    14091409
    1410         virtual const ast::Designation * visit( const ast::Designation * node ) {
     1410        virtual const ast::Designation * visit( const ast::Designation * node ) override final {
    14111411                if ( node->designators.empty() ) return node;
    14121412                os << "... designated by: " << endl;
     
    14211421        }
    14221422
    1423         virtual const ast::Init * visit( const ast::SingleInit * node ) {
     1423        virtual const ast::Init * visit( const ast::SingleInit * node ) override final {
    14241424                os << "Simple Initializer: ";
    14251425                safe_print( node->value );
     
    14271427        }
    14281428
    1429         virtual const ast::Init * visit( const ast::ListInit * node ) {
     1429        virtual const ast::Init * visit( const ast::ListInit * node ) override final {
    14301430                os << "Compound initializer: " << endl;
    14311431                ++indent;
     
    14451445        }
    14461446
    1447         virtual const ast::Init * visit( const ast::ConstructorInit * node ) {
     1447        virtual const ast::Init * visit( const ast::ConstructorInit * node ) override final {
    14481448                os << "Constructor initializer: " << endl;
    14491449                if ( node->ctor ) {
     
    14701470        }
    14711471
    1472         virtual const ast::Attribute * visit( const ast::Attribute * node ) {
     1472        virtual const ast::Attribute * visit( const ast::Attribute * node ) override final {
    14731473                if ( node->empty() ) return node;
    14741474                os << "Attribute with name: " << node->name;
     
    14811481        }
    14821482
    1483         virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) {
     1483        virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) override final {
    14841484                os << indent << "Types:" << endl;
    14851485                for ( const auto& i : *node ) {
  • src/AST/Stmt.hpp

    r1f1c102 rf53acdf8  
    380380};
    381381
    382 /// With statement `with (...) ...`
    383 class WithStmt final : public Stmt {
    384 public:
    385         std::vector<ptr<Expr>> exprs;
    386         ptr<Stmt> stmt;
    387 
    388         WithStmt( const CodeLocation & loc, std::vector<ptr<Expr>> && exprs, const Stmt * stmt,
    389                 std::vector<Label> && labels = {} )
    390         : Stmt(loc, std::move(labels)), exprs(std::move(exprs)), stmt(stmt) {}
    391 
    392         const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
    393 private:
    394         WithStmt * clone() const override { return new WithStmt{ *this }; }
    395         MUTATE_FRIEND
    396 };
    397 
    398382/// Any declaration in a (compound) statement.
    399383class DeclStmt final : public Stmt {
  • src/AST/SymbolTable.cpp

    r1f1c102 rf53acdf8  
    7373
    7474SymbolTable::SymbolTable()
    75 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 
     75: idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(),
    7676  prevScope(), scope( 0 ), repScope( 0 ) { ++*stats().count; }
    7777
     
    171171}
    172172
    173 void SymbolTable::addDeletedId( const DeclWithType * decl, const Node * deleter ) {
     173void SymbolTable::addDeletedId( const DeclWithType * decl, const Decl * deleter ) {
    174174        // default handling of conflicts is to raise an error
    175175        addId( decl, OnConflict::error(), nullptr, deleter );
     
    189189                        }
    190190                }
    191                 // does not need to be added to the table if both existing and added have a base that are 
     191                // does not need to be added to the table if both existing and added have a base that are
    192192                // the same
    193193                return true;
     
    209209        const std::string &id = decl->name;
    210210
    211         if ( ! typeTable ) { 
     211        if ( ! typeTable ) {
    212212                typeTable = TypeTable::new_ptr();
    213213        } else {
    214214                ++*stats().map_lookups;
    215215                auto existing = typeTable->find( id );
    216                 if ( existing != typeTable->end() 
    217                         && existing->second.scope == scope 
     216                if ( existing != typeTable->end()
     217                        && existing->second.scope == scope
    218218                        && addedTypeConflicts( existing->second.decl, decl ) ) return;
    219219        }
    220        
     220
    221221        lazyInitScope();
    222222        ++*stats().map_mutations;
     
    237237                ++*stats().map_lookups;
    238238                auto existing = structTable->find( id );
    239                 if ( existing != structTable->end() 
    240                         && existing->second.scope == scope 
     239                if ( existing != structTable->end()
     240                        && existing->second.scope == scope
    241241                        && addedDeclConflicts( existing->second.decl, decl ) ) return;
    242242        }
     
    256256                ++*stats().map_lookups;
    257257                auto existing = enumTable->find( id );
    258                 if ( existing != enumTable->end() 
    259                         && existing->second.scope == scope 
     258                if ( existing != enumTable->end()
     259                        && existing->second.scope == scope
    260260                        && addedDeclConflicts( existing->second.decl, decl ) ) return;
    261261        }
    262        
     262
    263263        lazyInitScope();
    264264        ++*stats().map_mutations;
     
    279279                ++*stats().map_lookups;
    280280                auto existing = unionTable->find( id );
    281                 if ( existing != unionTable->end() 
    282                         && existing->second.scope == scope 
     281                if ( existing != unionTable->end()
     282                        && existing->second.scope == scope
    283283                        && addedDeclConflicts( existing->second.decl, decl ) ) return;
    284284        }
     
    298298                ++*stats().map_lookups;
    299299                auto existing = traitTable->find( id );
    300                 if ( existing != traitTable->end() 
    301                         && existing->second.scope == scope 
     300                if ( existing != traitTable->end()
     301                        && existing->second.scope == scope
    302302                        && addedDeclConflicts( existing->second.decl, decl ) ) return;
    303303        }
     
    309309
    310310
    311 void SymbolTable::addWith( const std::vector< ptr<Expr> > & withExprs, const Node * withStmt ) {
     311void SymbolTable::addWith( const std::vector< ptr<Expr> > & withExprs, const Decl * withStmt ) {
    312312        for ( const Expr * expr : withExprs ) {
    313313                if ( ! expr->result ) continue;
    314314                const Type * resTy = expr->result->stripReferences();
    315315                auto aggrType = dynamic_cast< const ReferenceToType * >( resTy );
    316                 assertf( aggrType, "WithStmt expr has non-aggregate type: %s", 
     316                assertf( aggrType, "WithStmt expr has non-aggregate type: %s",
    317317                        toString( expr->result ).c_str() );
    318318                const AggregateDecl * aggr = aggrType->aggr();
    319                 assertf( aggr, "WithStmt has null aggregate from type: %s", 
     319                assertf( aggr, "WithStmt has null aggregate from type: %s",
    320320                        toString( expr->result ).c_str() );
    321                
     321
    322322                addMembers( aggr, expr, OnConflict::deleteWith( withStmt ) );
    323323        }
     
    373373        }
    374374
    375         /// gets the declaration for the function acting on a type specified by otype key, 
     375        /// gets the declaration for the function acting on a type specified by otype key,
    376376        /// nullptr if none such
    377         const FunctionDecl * getFunctionForOtype( 
     377        const FunctionDecl * getFunctionForOtype(
    378378                        const DeclWithType * decl, const std::string & otypeKey ) {
    379379                auto func = dynamic_cast< const FunctionDecl * >( decl );
     
    383383}
    384384
    385 bool SymbolTable::removeSpecialOverrides( 
     385bool SymbolTable::removeSpecialOverrides(
    386386                SymbolTable::IdData & data, SymbolTable::MangleTable::Ptr & mangleTable ) {
    387         // if a type contains user defined ctor/dtor/assign, then special rules trigger, which 
    388         // determine the set of ctor/dtor/assign that can be used  by the requester. In particular, 
    389         // if the user defines a default ctor, then the generated default ctor is unavailable, 
    390         // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 
    391         // field ctors are available. If the user defines any ctor then the generated default ctor 
    392         // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 
    393         // anything that looks like a copy constructor, then the generated copy constructor is 
     387        // if a type contains user defined ctor/dtor/assign, then special rules trigger, which
     388        // determine the set of ctor/dtor/assign that can be used  by the requester. In particular,
     389        // if the user defines a default ctor, then the generated default ctor is unavailable,
     390        // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated
     391        // field ctors are available. If the user defines any ctor then the generated default ctor
     392        // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines
     393        // anything that looks like a copy constructor, then the generated copy constructor is
    394394        // unavailable, and likewise for the assignment operator.
    395395
     
    450450                // if this is the first user-defined function, delete non-user-defined overloads
    451451                std::vector< MangleTable::value_type > deleted;
    452                
     452
    453453                for ( const auto& entry : *mangleTable ) {
    454454                        // skip decls that aren't functions or are for the wrong type
     
    489489                        if ( dataIsCopyFunc ) {
    490490                                // remove current function if exists a user-defined copy function
    491                                 // since the signatures for copy functions don't need to match exactly, using 
     491                                // since the signatures for copy functions don't need to match exactly, using
    492492                                // a delete statement is the wrong approach
    493493                                if ( InitTweak::isCopyFunction( decl ) ) return false;
     
    499499                }
    500500        }
    501        
     501
    502502        // nothing (more) to fix, return true
    503503        return true;
     
    525525
    526526bool SymbolTable::addedIdConflicts(
    527                 const SymbolTable::IdData & existing, const DeclWithType * added, 
    528                 SymbolTable::OnConflict handleConflicts, const Node * deleter ) {
    529         // if we're giving the same name mangling to things of different types then there is something 
     527                const SymbolTable::IdData & existing, const DeclWithType * added,
     528                SymbolTable::OnConflict handleConflicts, const Decl * deleter ) {
     529        // if we're giving the same name mangling to things of different types then there is something
    530530        // wrong
    531531        assert( (isObject( added ) && isObject( existing.id ) )
    532532                || ( isFunction( added ) && isFunction( existing.id ) ) );
    533        
     533
    534534        if ( existing.id->linkage.is_overrideable ) {
    535535                // new definition shadows the autogenerated one, even at the same scope
    536536                return false;
    537         } else if ( existing.id->linkage.is_mangled 
    538                         || ResolvExpr::typesCompatible( 
     537        } else if ( existing.id->linkage.is_mangled
     538                        || ResolvExpr::typesCompatible(
    539539                                added->get_type(), existing.id->get_type(), SymbolTable{} ) ) {
    540                
     540
    541541                // it is a conflict if one declaration is deleted and the other is not
    542542                if ( deleter && ! existing.deleter ) {
     
    555555                if ( isDefinition( added ) && isDefinition( existing.id ) ) {
    556556                        if ( handleConflicts.mode == OnConflict::Error ) {
    557                                 SemanticError( added, 
    558                                         isFunction( added ) ? 
    559                                                 "duplicate function definition for " : 
     557                                SemanticError( added,
     558                                        isFunction( added ) ?
     559                                                "duplicate function definition for " :
    560560                                                "duplicate object definition for " );
    561561                        }
     
    572572}
    573573
    574 void SymbolTable::addId( 
    575                 const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr, 
    576                 const Node * deleter ) {
     574void SymbolTable::addId(
     575                const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr,
     576                const Decl * deleter ) {
    577577        ++*stats().add_calls;
    578578        const std::string &name = decl->name;
     
    581581        std::string mangleName;
    582582        if ( decl->linkage.is_overrideable ) {
    583                 // mangle the name without including the appropriate suffix, so overridable routines 
     583                // mangle the name without including the appropriate suffix, so overridable routines
    584584                // are placed into the same "bucket" as their user defined versions.
    585585                mangleName = Mangle::mangle( decl, Mangle::Mode{ Mangle::NoOverrideable } );
     
    588588        }
    589589
    590         // this ensures that no two declarations with the same unmangled name at the same scope 
     590        // this ensures that no two declarations with the same unmangled name at the same scope
    591591        // both have C linkage
    592592        if ( decl->linkage.is_mangled ) {
     
    596596                }
    597597