Pragmatic directives: Difference between revisions
No edit summary |
|||
(9 intermediate revisions by 5 users not shown) | |||
Line 305: | Line 305: | ||
Additionally, parsing words sometimes alter compiler behavior. For example, the compiler uses type information from <code>TYPED:</code> words for optimizations. |
Additionally, parsing words sometimes alter compiler behavior. For example, the compiler uses type information from <code>TYPED:</code> words for optimizations. |
||
=={{header|FreeBASIC}}== |
|||
FreeBASIC does not have pragmatic directives in the traditional sense. |
|||
However, it has several built-in keywords and functions that can affect program behavior in a similar way to pragmatic directives in other languages. |
|||
Thus, FreeBASIC has keywords such as <code>Public</code> and <code>Private</code> that can change the visibility of variables and functions within a module. |
|||
<syntaxhighlight lang="vbnet">Private Sub i_am_private |
|||
End Sub |
|||
Public Sub i_am_public |
|||
End Sub</syntaxhighlight> |
|||
It also has keywords like <code>CDecl</code>, <code>Pascal</code> and <code>StdCall</code> that can change the calling convention of a function. |
|||
Cdecl is usually the default calling convention for C compilers and is used almost exclusively on Unix, Linux, *BSD, and DOS-like systems. |
|||
<syntaxhighlight lang="vbnet">' declaring 'strcpy' from the standard C library |
|||
Declare Function strcpy Cdecl Alias "strcpy" (Byval dest As ZString Ptr, Byval src As ZString Ptr) As ZString Ptr</syntaxhighlight> |
|||
Pascal is the default calling convention for procedures in Microsoft QuickBASIC and is the standard convention used in the Windows 3.1 API. |
|||
<syntaxhighlight lang="vbnet">Declare Function MyFunctionPascal Pascal Alias "MyFunction" (param As Integer) As Integer</syntaxhighlight> |
|||
Stdcall is the default calling convention on Windows and the most common in BASIC languages and the Windows API. |
|||
<syntaxhighlight lang="vbnet">Declare Function MyFunc1 Stdcall (param1 As Integer, param2 As Integer) As Integer</syntaxhighlight> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
Line 385: | Line 408: | ||
3 :'y.]y=.7' 8 |
3 :'y.]y=.7' 8 |
||
7</syntaxhighlight> |
7</syntaxhighlight> |
||
=={{header|Java}}== |
|||
The closest things which Java has to pragmatic directives are annotations which begin with the @ character. |
|||
<syntaxhighlight lang="java"> |
|||
import java.util.ArrayList; |
|||
import java.util.Arrays; |
|||
import java.util.List; |
|||
public final class PragmaticDirectives { |
|||
public static void main(String[] aArgs) { |
|||
/* Take no action */ |
|||
} |
|||
@FunctionalInterface |
|||
public interface Adder { // This annotation indicates a functional interface, |
|||
abstract int add(int a, int b); // which has exactly one abstract method. |
|||
} |
|||
@Deprecated |
|||
public void Display() { |
|||
System.out.println("This author is indicating that this method is deprecated"); |
|||
} |
|||
@SuppressWarnings("unchecked") |
|||
public void uncheckedWarning() { |
|||
List words = new ArrayList(); |
|||
words.add("hello"); |
|||
System.out.println("THe compiler is warning that the generic type declaration is missing."); |
|||
System.out.println("The correct syntax is: List<String> words = new ArrayList<String>()"); |
|||
} |
|||
@SafeVarargs |
|||
public static <T> List<T> list(final T... items) { |
|||
System.out.println("This annotation suppresses unchecked warnings about a non-reifiable variable arity type"); |
|||
return Arrays.asList(items); |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|jq}}== |
|||
'''Works with jq, the C implementation of jq''' |
|||
'''Works with gojq, the Go implementation of jq''' |
|||
jq supports directives for including or importing a jq module, as exemplified by: |
|||
<pre> |
|||
include "m" {"search": "."}; |
|||
</pre> |
|||
In this example, the module "m.jq" in the present working directory would be "transcluded" as if by inlining the contents of the file m.jq. |
|||
The "search" key specifies a pathname or array of pathnames to be searched. |
|||
Note that the JSON object that may be specified in an "include" directive must be a constant. |
|||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
Line 575: | Line 654: | ||
trace -- allow or disallow debugging (source code line-by-line tracing) <br> |
trace -- allow or disallow debugging (source code line-by-line tracing) <br> |
||
debug -- turn debugging info generation on or off <br> |
debug -- turn debugging info generation on or off <br> |
||
nested_globals -- fine-grained scope control, nested_locals is the complementary option <br> |
|||
The last two are related: without debug completely removes all tracing and diagnostics for a specific file (primarily intended for use in well-tested system routines), whereas (under with debug, which is the default) with/without trace can make debugging less tedious by not stopping on every line of irrelevant (user-selected) code, although dumps still contain a full call stack. Some other options, specifically indirect_includes, inline, and digital stamps, exist solely for compatability and are completely ignored. |
The last two are related: without debug completely removes all tracing and diagnostics for a specific file (primarily intended for use in well-tested system routines), whereas (under with debug, which is the default) with/without trace can make debugging less tedious by not stopping on every line of irrelevant (user-selected) code, although dumps still contain a full call stack. Some other options, specifically indirect_includes, inline, and digital stamps, exist solely for compatability and are completely ignored. |
||
Line 661: | Line 741: | ||
Get-Help about_Requires |
Get-Help about_Requires |
||
</syntaxhighlight> |
</syntaxhighlight> |
||
=={{header|PureBasic}}== |
|||
PureBasic supports several pragmatic directives, also known as '''[https://www.purebasic.com/documentation/reference/compilerdirectives.html compiler directives]'''. |
|||
<code>CompilerIf…CompilerElseIf…CompilerElse…CompilerEndIf</code>: allows certain parts of the code to be compiled depending on the evaluation of a constant expression. |
|||
<syntaxhighlight lang="vb">CompilerIf #PB_Compiler_OS = #PB_OS_Linux |
|||
; some Linux specific code |
|||
CompilerElse |
|||
; some code for other operating systems |
|||
CompilerEndIf</syntaxhighlight> |
|||
<code>CompilerSelect…CompilerCase…CompilerDefault…CompilerEndSelect</code>: Allows you to select which code to compile based on a constant numeric value. |
|||
<syntaxhighlight lang="vb">CompilerSelect #PB_Compiler_OS |
|||
CompilerCase #PB_OS_MacOS |
|||
; some Mac OS |
|||
CompilerCase #PB_OS_Linux |
|||
; some Linux specific code |
|||
CompilerEndSelect</syntaxhighlight> |
|||
<code>CompilerError</code> and <code>CompilerWarning</code>: generate an error or a warning, respectively. |
|||
<syntaxhighlight lang="vb">CompilerIf #PB_Compiler_OS = #PB_OS_Linux |
|||
CompilerError "Linux is not supported, sorry." |
|||
CompilerElse |
|||
CompilerWarning "OS supported, you can now comment me." |
|||
CompilerEndIf</syntaxhighlight> |
|||
<code>EnableExplicit</code> and <code>DisableExplicit1</code>: Enable or disable explicit mode. When enabled, all variables not explicitly declared with Define, Global, Protected, or Static will not be accepted and the compiler will generate an error. |
|||
<syntaxhighlight lang="vb">EnableExplicit |
|||
Defines |
|||
a = 20 ; Ok, as declared with 'Define' |
|||
b = 10 ; Will raise an error here</syntaxhighlight> |
|||
<code>EnableASM</code> and <code>DisableASM</code>: Enable or disable the inline assembler. When enabled, all assembler keywords are available directly in the source code. |
|||
<syntaxhighlight lang="vb">; x86 assembly example |
|||
Test = 10 |
|||
EnableASM |
|||
MOV dword [v_Test],20 |
|||
DisableASM |
|||
DebugTest ; Will be 20</syntaxhighlight> |
|||
It is important to note that the scope of these directives is global, that is, they affect all code after them until a directive is found that disables them or until the end of the code file. |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
Line 861: | Line 982: | ||
For external routines, the defaults are used. <br><br> |
For external routines, the defaults are used. <br><br> |
||
=={{header|RPL}}== |
|||
Pragmatic directives are given through system flags that can bet with the <code>SF</code> and <code>CF</code> commands anywhere in a program. |
|||
System flags are a legacy of programmable calculators and unfortunately, which flag to set or reset for a specific directive depends on the calculator model you are using. |
|||
As an example, here are the directives controlled by flags on HP-28 models: |
|||
* LAST variable activated |
|||
* Immediate evaluation of constants (e, pi...) and functions |
|||
* length of binary words |
|||
* display and print formats |
|||
* decimal sign and object separator |
|||
* real number display format |
|||
* sound on/off |
|||
* underflow/overflow error handling |
|||
Fortunately, some of them can also be operated through language commands, such as <code>STWS</code> (defines the length of binary words) or <code>RAD</code> (defines radian as the trigonometric unit). |
|||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
Line 900: | Line 1,037: | ||
Import statements can appear anywhere a variable declaration is allowed and in particular within conditional structures. This enables us to do things such as the following: |
Import statements can appear anywhere a variable declaration is allowed and in particular within conditional structures. This enables us to do things such as the following: |
||
<syntaxhighlight lang=" |
<syntaxhighlight lang="wren">/* windows.wren */ |
||
class Windows { |
class Windows { |
||
Line 907: | Line 1,044: | ||
}</syntaxhighlight> |
}</syntaxhighlight> |
||
<syntaxhighlight lang=" |
<syntaxhighlight lang="wren">/* linux.wren */ |
||
class Linux { |
class Linux { |
||
Line 914: | Line 1,051: | ||
}</syntaxhighlight> |
}</syntaxhighlight> |
||
<syntaxhighlight lang=" |
<syntaxhighlight lang="wren">/* Pragmatic_directives.wren */ |
||
import "os" for Platform |
import "os" for Platform |
||
Line 920: | Line 1,057: | ||
var os |
var os |
||
if (Platform.isWindows) { |
if (Platform.isWindows) { |
||
import "/windows" for Windows |
import "./windows" for Windows |
||
os = Windows |
os = Windows |
||
} else { |
} else { |
||
import "/linux" for Linux |
import "./linux" for Linux |
||
os = Linux |
os = Linux |
||
} |
} |
||
Line 931: | Line 1,068: | ||
From the last script, when run on a Linux system. |
From the last script, when run on a Linux system. |
||
<pre> |
<pre> |
||
$ wren_cli |
$ wren_cli Pragmatic_directives.wren |
||
Using Linux which has a "\n" line separator. |
Using Linux which has a "\n" line separator. |
||
</pre> |
</pre> |
Latest revision as of 19:24, 28 June 2024
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
Pragmatic directives cause the language to operate in a specific manner, allowing support for operational variances within the program code (possibly by the loading of specific or alternative modules).
- Task
List any pragmatic directives supported by the language, and demonstrate how to activate and deactivate the pragmatic directives and to describe or demonstrate the scope of effect that the pragmatic directives have within a program.
6502 Assembly
These are common to most assemblers but syntax may vary. Place them in your source code file. As with code, all of these can be deactivated by commenting them out.
org $XXXX
: Tells the assembler which memory address to begin assembling at. The instruction after this directive will begin at that address, and then code will be placed sequentially until the end of file or the next ORG directive is reached.equ
: Equates a label to a specific numeric value. Each instance of that label in your code becomes a constant if preceded by a # and a memory address otherwise.include "filename"
: Adds an additional file to your source code. The assembler treats the contents as 6502 instructions when assembling. For most assemblers the location of theinclude
statement matters, since it is treated as if the contents were copy-pasted inline.incbin "filename"
: Adds a binary file to your source code. For most assemblers the location of theincbin
statement matters, since it is treated as if the contents were copy-pasted inline.ifdef
/ifndef
/else
/endif
: The assembler will skip anything inside an IFDEF block if the designated label wasn't defined. IFNDEF and ELSE are the opposite. To make an IFDEF statement true, you only need to have that label defined in your source. (The value doesn't matter as long as it appears.) Here's an example:
NMOS_6502 equ 1
ifdef NMOS_6502
txa
pha
else
phx ;NMOS_6502 doesn't have this instruction.
endif ; every ifdef/ifndef needs an endif
db
/dw
/byte
/word
: Defines a data block. The assembler treats these values as arbitrary bytes rather than machine instructions. Used for tables of values, etc.
align #
Fills in the next # bytes with padding (typically zero, but this value can be adjusted in your assembler's settings. Useful for preventing wasted cycles that occur when crossing a page boundary.
macro
: Defines a macro. Any time the macro name appears in your source document, the assembler replaces it with the definition. Any parameters supplied to the macro are also plugged in. This is useful for parameter passing which would otherwise be very tedious. Every macro must end with anendm
.
8086 Assembly
These are common to most assemblers but syntax may vary. Place them in your source code file. As with code, all of these can be deactivated by commenting them out.
.data
: Marks the beginning of the data segment. You can load this segment into a segment register with@data
rather thanseg .data
..code
: Marks the beginning of the code segment. You can load this segment into a segment register with@code
rather thanseg .code
.equ
: Equates a label to a specific numeric value.
include filename
: Adds an additional file to your source code. The assembler treats the contents as 6502 instructions when assembling. For most assemblers the location of theinclude
statement matters, since it is treated as if the contents were copy-pasted inline. UASM doesn't require quotation marks around the filename.
incbin filename
: Adds a binary file to your source code. For most assemblers the location of theincbin
statement matters, since it is treated as if the contents were copy-pasted inline. UASM doesn't require quotation marks around the filename.
ifdef
/ifndef
/else
/endif
: The assembler will skip anything inside an IFDEF block if the designated label wasn't defined. IFNDEF and ELSE are the opposite. To make an IFDEF statement true, you only need to have that label defined in your source. (The value doesn't matter as long as it appears.)
db
/dw
/byte
/word
: Defines a data block. The assembler treats these values as arbitrary bytes rather than machine instructions. Used for tables of values, etc.
BYTE n DUP (k)
: Fills in the next n bytes with the value k. This is useful for creating user ram in your data segment
macro
: Defines a macro. Any time the macro name appears in your source document, the assembler replaces it with the definition. Any parameters supplied to the macro are also plugged in. This is useful for parameter passing which would otherwise be very tedious. Every macro must end with anendm
.
byte ptr
/word ptr
: Tells the assembler that the value after this directive is a memory address rather than a constant. This is useful when using labels and the command you're using is somewhat ambiguous about the data size or whether this is an address or a constant.
seg
: When using a labeled code section or memory address as an operand, placingseg
in front tells the assembler you wish to load the segment that memory address is located in, rather than the address itself.
offset
: When using a labeled code section or memory address as an operand, placingoffset
in front tells the assembler you wish to load the offset of that address from the beginning of its segment.
Ada
Some common language defined pragmas:
- pragma assert(expression, error_message)
- pragma Import(...) and pragma Export(...) to interface other languages, commonly C
- pragma Inline(function_name) perform inline expansion of the function
- pragma Optimize(Time/Space/Off) Implementation defined, attempts to optimize memory usage for speed or time.
- pragma Pack(type) attempts to minimize memory usage for the type, even if it means slower memory access. A representation clause specifying bit size is usually used instead of this.
- pragma Suppress(identifier) and pragma Unsuppress(identifier) for enabling/disabling any of the many language checks.
Some pragmas are also implementation defined, the commonly used GNAT provides many, such as:
- pragma Unreferenced(name) suppresses warnings about unused entities, and raises warnings if they are in fact referenced.
There are far too many pragmas to list here, but a standard informative list can be found in Annex L of the documentation if you have it installed. Or found at:
ALGOL 68
File: Pragmatic_directives.a68
#!/usr/local/bin/a68g --script #
PRAGMAT portcheck PRAGMAT
PR portcheck PR
BEGIN PR heap=256M PR # algol68g pragma #
~
END;
PROC (REAL)REAL s = sin();
SKIP
Output:
10 PROC (REAL)REAL s = sin(); 1 a68g: warning: 1: generic-argument is an extension (detected in particular-program).
BASIC
Some versions of basic support the use of system trace directives that allow the program line or line number to be output.
10 TRON: REM activate system trace pragma
20 TROFF: REM deactivate system trace pragma
IS-BASIC
TRACE ON
TRACE OFF
QBasic
TRON : REM activate system trace pragma
TROFF : REM deactivate system trace pragma
REM QBasic debugging features make these instructions unnecessary
END
C
The C Preprocessor is well explained on the GNU site. The pragma page is here.
/*Almost every C program has the below line,
the #include preprocessor directive is used to
instruct the compiler which files to load before compiling the program.
All preprocessor commands begin with #
*/
#include<stdio.h>
/*The #define preprocessor directive is often used to create abbreviations for code segments*/
#define Hi printf("Hi There.");
/*It can be used, or misused, for rather innovative uses*/
#define start int main(){
#define end return 0;}
start
Hi
/*And here's the nice part, want your compiler to talk to you ?
Just use the #warning pragma if you are using a C99 compliant compiler
like GCC*/
#warning "Don't you have anything better to do ?"
#ifdef __unix__
#warning "What are you doing still working on Unix ?"
printf("\nThis is an Unix system.");
#elif _WIN32
#warning "You couldn't afford a 64 bit ?"
printf("\nThis is a 32 bit Windows system.");
#elif _WIN64
#warning "You couldn't afford an Apple ?"
printf("\nThis is a 64 bit Windows system.");
#endif
end
/*Enlightened ?*/
On compilation and output, the compiler type is detected rather than the actual OS :
C:\rosettaCode>gcc pragmatic.c pragmatic.c:22:2: warning: #warning "Don't you have anything better to do ?" pragmatic.c:28:2: warning: #warning "You couldn't afford a 64 bit ?" C:\rosettaCode>a Hi There. This is a 32 bit Windows system.
Common Lisp
Common Lisp usually works with a runtime system which contains an incremental compiler and a file compiler. Various ways are possible to influence the runtime system and the compiler.
Declarations
- a data allocation can be declared to be done on the stack (if the compiler supports that)
- the optimization settings for the compiler can be set for these qualities: debug, safety, space, speed, compilation speed
- functions can be declared for inline compilation (if the compiler supports that)
Feature Expressions
Common Lisp provides a way for conditional reading or ignoring of expressions. A variable lists the available features of an implementation.
Clozure Common Lisp:
? *features* (:EASYGUI :ASDF2 :ASDF :HEMLOCK :APPLE-OBJC-2.0 :APPLE-OBJC :PRIMARY-CLASSES :COMMON-LISP :OPENMCL :CCL :CCL-1.2 :CCL-1.3 :CCL-1.4 :CCL-1.5 :CCL-1.6 :CCL-1.7 :CCL-1.8 :CLOZURE :CLOZURE-COMMON-LISP :ANSI-CL :UNIX :OPENMCL-UNICODE-STRINGS :OPENMCL-NATIVE-THREADS :OPENMCL-PARTIAL-MOP :MCL-COMMON-MOP-SUBSET :OPENMCL-MOP-2 :OPENMCL-PRIVATE-HASH-TABLES :X86-64 :X86_64 :X86-TARGET :X86-HOST :X8664-TARGET :X8664-HOST :DARWIN-HOST :DARWIN-TARGET :DARWINX86-TARGET :DARWINX8664-TARGET :DARWINX8664-HOST :64-BIT-TARGET :64-BIT-HOST :DARWIN :LITTLE-ENDIAN-TARGET :LITTLE-ENDIAN-HOST)
These features can then use to conditionally execute code:
#+UNIX(print "this is a unix system")
Above would execute the print statement only if the Lisp system has a feature called UNIX.
#-COCOA(require "cocoa")
Above would check for the COCOA feature and if not present, load the library. The library is also expected to later push the feature COCOA to the features list. Reading this code then later would ignore the require statement.
Delphi
Delphi has dozens of directive that change the way the compiler and the language work.
Here is a link describing the way directive work in general:
Here is a list of all the directive available in current versions of Delphi:
https://docwiki.embarcadero.com/RADStudio/Sydney/en/Delphi_Compiler_Directives_(List)_Index
// Some examples
{$R *.dfm}
{$R WorldMaps.res}
{$optimization on,hints off}
{$B+}
{$R- Turn off range checking}
{$I TYPES.INC}
{$M 32768,40960}
{$DEFINE Debug}
{$IFDEF Debug}
{$ENDIF}
procedure DivMod(Dividend: Cardinal; Divisor: Word;
var Result, Remainder: Word);
{$IFDEF PUREPASCAL}
begin
Result := Dividend div Divisor;
Remainder := Dividend mod Divisor;
end;
{$ELSE !PUREPASCAL}
{$IFDEF X86ASM}
asm // StackAlignSafe
PUSH EBX
MOV EBX,EDX
MOV EDX,EAX
SHR EDX,16
DIV BX
MOV EBX,Remainder
MOV [ECX],AX
MOV [EBX],DX
POP EBX
end;
{$ENDIF X86ASM}
{$ENDIF !PUREPASCAL}
- Output:
D
The -d compiler switch allows deprecated D features in a program. It allows some deprecated features of C language, and user code wrapped inside deprecated{}.
Erlang
Erlang pragmas are called module attributes. The compile attribute, ex:
-compile( [compressed, {inline,[pi/0]}] ).
will add the compiler option 'compressed' when the module is compiled and inline the function pi/0.
The file module attribute look like
-file( "kalle", 98 ).
and will change the ?FILE macro from the file name to "kalle" and the ?LINE macro from the line number to 98.
More module attributes at [1].
Factor
Factor provides the following compiler declarations which can be used immediately following a word definition:
- inline
- Declares the most recently defined word as an inline word. The optimizing compiler copies definitions of inline words when compiling calls to them. Combinators must be inlined in order to compile with the optimizing compiler. For any other word, inlining is merely an optimization.
- foldable
- Declares that the most recently defined word may be evaluated at compile-time if all inputs are literal. Foldable words must satisfy a very strong contract:
- foldable words must not have any observable side effects
- foldable words must halt — for example, a word computing a series until it coverges should not be foldable, since compilation will not halt in the event the series does not converge
- both inputs and outputs of foldable words must be immutable
- Most operations on numbers are foldable. For example,
2 2 +
compiles to a literal4
, since+
is declared foldable.
- Most operations on numbers are foldable. For example,
- flushable
- Declares that the most recently defined word has no side effects, and thus calls to this word may be pruned by the compiler if the outputs are not used.
- Note that many words are flushable but not foldable, for example
clone
and<array>
.
- Note that many words are flushable but not foldable, for example
- recursive
- Declares the most recently defined word as a recursive word. This declaration is only required for inline words which call themselves.
- deprecated
- Declares the most recently defined word as deprecated. Code that uses deprecated words continues to function normally; the errors are purely informational. However, code that uses deprecated words should be updated, for the deprecated words are intended to be removed soon.
Additionally, parsing words sometimes alter compiler behavior. For example, the compiler uses type information from TYPED:
words for optimizations.
FreeBASIC
FreeBASIC does not have pragmatic directives in the traditional sense. However, it has several built-in keywords and functions that can affect program behavior in a similar way to pragmatic directives in other languages.
Thus, FreeBASIC has keywords such as Public
and Private
that can change the visibility of variables and functions within a module.
Private Sub i_am_private
End Sub
Public Sub i_am_public
End Sub
It also has keywords like CDecl
, Pascal
and StdCall
that can change the calling convention of a function.
Cdecl is usually the default calling convention for C compilers and is used almost exclusively on Unix, Linux, *BSD, and DOS-like systems.
' declaring 'strcpy' from the standard C library
Declare Function strcpy Cdecl Alias "strcpy" (Byval dest As ZString Ptr, Byval src As ZString Ptr) As ZString Ptr
Pascal is the default calling convention for procedures in Microsoft QuickBASIC and is the standard convention used in the Windows 3.1 API.
Declare Function MyFunctionPascal Pascal Alias "MyFunction" (param As Integer) As Integer
Stdcall is the default calling convention on Windows and the most common in BASIC languages and the Windows API.
Declare Function MyFunc1 Stdcall (param1 As Integer, param2 As Integer) As Integer
Go
Go has a feature called build constraints that work on the level of whole files. A comment line reading
// +build <expression>
will cause the entire file to be excluded from a build unless <expression> is true. The elements, called tags, in the expression are typically things like the target operating system or hardware architecture. For example
// +build linux
will include the file if the target OS is linux, but will exclude the file otherwise. Arbitrary tags can be passed on the command line of the go command. A file could begin
// +build Tuesday
and the build command
go install -tags `date +%A`
would only include the file on Tuesdays.
Icon and Unicon
Icon and Unicon have a number of pragmatic modes. Most of these are controlled via keywords (See Special_variables#Icon_and_Unicon)).
Additionally, tracing can be controlled via the environment variable 'TRACE'.
J
J's foreign global parameters possibly qualify as pragmatic directives.
They are analogous to setting (or reading) variables.
Here's a list of the settings:
9!:1 random seed (incomplete specification of state -- see 9!:45) 9!:3 default display for non-nouns 9!:7 box drawing characters 9!:9 error messages 9!:11 print precision 9!:17 centering (or not) when box contents are smaller than boxes 9!:19 comparison tolerance 9!:21 memory limit 9!:25 security level 9!:27 text of immediate execution phrase 9!:29 enable immediate execution phrase 9!:33 execution time limit 9!:35 disable (or re-enable) assertions 9!:37 output control 9!:39 locales' hash table size 9!:41 retain (or not) whitespace and comments in explicit definitions 9!:43 which random number generator to use? 9!:45 what is the current state of that rng? 9!:49 enable reserved words for argument names
For example,
9!:25]1
disables access to the file system (and disables some other features, including the ability to exit the program, because the system exit mechanism is a system feature and thus not trusted). You cannot turn this off after it has been turned on (so you will need to shut down J and start it again if you want to use those features).
Or, for example, y is the usual name for the right argument of a verb.
3 :'y' 8
8
But y is also a regular variable. So J also offers a reserved word y. which serves the same role. But this is disabled by default (because mostly it's just an unnecessary complication).
3 :'y.' 8
|spelling error
But you can enable the reserved word mechanism:
9!:49]1
3 :'y.' 8
8
3 :'y.[y=.7' 8
8
3 :'y.]y=.7' 8
7
Java
The closest things which Java has to pragmatic directives are annotations which begin with the @ character.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public final class PragmaticDirectives {
public static void main(String[] aArgs) {
/* Take no action */
}
@FunctionalInterface
public interface Adder { // This annotation indicates a functional interface,
abstract int add(int a, int b); // which has exactly one abstract method.
}
@Deprecated
public void Display() {
System.out.println("This author is indicating that this method is deprecated");
}
@SuppressWarnings("unchecked")
public void uncheckedWarning() {
List words = new ArrayList();
words.add("hello");
System.out.println("THe compiler is warning that the generic type declaration is missing.");
System.out.println("The correct syntax is: List<String> words = new ArrayList<String>()");
}
@SafeVarargs
public static <T> List<T> list(final T... items) {
System.out.println("This annotation suppresses unchecked warnings about a non-reifiable variable arity type");
return Arrays.asList(items);
}
}
jq
Works with jq, the C implementation of jq
Works with gojq, the Go implementation of jq
jq supports directives for including or importing a jq module, as exemplified by:
include "m" {"search": "."};
In this example, the module "m.jq" in the present working directory would be "transcluded" as if by inlining the contents of the file m.jq. The "search" key specifies a pathname or array of pathnames to be searched.
Note that the JSON object that may be specified in an "include" directive must be a constant.
Julia
Julia has a number of macros which act as compiler directives. For example, the @inbounds
macro disables runtime checking of array bounds within a block of code marked by this macro, which sometimes improves performance. Example:
x = rand(100, 100)
y = rand(100, 100)
@inbounds begin
for i = 1:100
for j = 1:100
x[i, j] *= y[i, j]
y[i, j] += x[i, j]
end
end
end
Kotlin
The closest things which Kotlin has to pragmatic directives are annotations which always begin with the @ character. For example, the following code would normally produce a compiler warning that the variable 's' is never used. However, the presence of the @Suppress annotation suppresses the warning:
// version 1.0.6
@Suppress("UNUSED_VARIABLE")
fun main(args: Array<String>) {
val s = "To be suppressed"
}
Lua
Lua itself really doesn't have anything equivalent. However, if being used in a mixed/hosted/embedded environment, the ffi
library might be encountered, which supports pragma pack
to facilitate native type interchange:
ffi = require("ffi")
ffi.cdef[[
#pragma pack(1)
typedef struct { char c; int i; } foo;
#pragma pack(4)
typedef struct { char c; int i; } bar;
]]
print(ffi.sizeof(ffi.new("foo")))
print(ffi.sizeof(ffi.new("bar")))
- Output:
5 8
Mathematica /Wolfram Language
Mathematica makes no formal difference between any normal and "specific" operation of the language. Any possible desired effect can be achieved by calling a function or setting a variable. Function calls are traced using the Trace[] function.
NetRexx
NetRexx provides three pragma-like instructions: OPTIONS, NUMERIC and TRACE.
- OPTIONS provides the ability to pass special requests to the language processor (i.e. a compiler or interpreter).
- The syntax is:
options wordlist;
- where wordlist is one or more symbols separated by blanks. The individual words in wordlist might control optimizations, enforce standards, enable implementation-dependent features, etc.
- The current default settings of OPTIONS is:
options - nobinary nocomments nocompact console crossref decimal nodiag noexplicit noformat java logo noreplace nosavelog nosourcedir - nostrictargs nostrictassign nostrictcase nostrictimport nostrictprops nostrictsignal nosymbols trace2 noutf8 verbose3
- NUMERIC is used to change the way in which arithmetic operations are carried out by a program.
- The syntax is:
numeric digits [exprd]; numeric form [scientific | engineering];
- numeric digits controls the precision under which arithmetic operations will be evaluated. The default for exprd is 9 i.e. numeric digits 9.
There is normally no limit to the value for numeric digits (except the constraints imposed by the amount of storage and other resources available) but note that high precisions are likely to be expensive in processing time. - numeric form controls which form of exponential notation is to be used for the results of operations.
- numeric digits controls the precision under which arithmetic operations will be evaluated. The default for exprd is 9 i.e. numeric digits 9.
- TRACE is used to control the tracing of the execution of NetRexx methods, and is primarily used for debugging.
- The Syntax is:
trace tracesetting trace var [varlist]
- where tracesetting is one of:
- all
- All clauses (except null clauses without commentary) which are in methods and which are executed after the trace instruction will be traced.
- methods
- All method clauses in the class will be traced when the method they introduce is invoked, together with the values of the arguments passed to each method.
- off
- turns tracing off.
- results
- similar to trace all for the clauses in a method with the addition that the results of all expression evaluations and any results assigned to a variable by an assignment, loop, or parse instruction are also traced.
- and varlist provides a list of variables which will be monitored during execution.
Nim
Nim provides a great number of directives known as pragmas. It is not possible to describe them here. A pragma (or list of pragmas) starts with {.
and ends with .}
. It may possess arguments. Here are some kinds of pragmas:
- – pragmas such as
pure
applicable to types; - – pragmas such as
noSideEffect
,compileTime
applicable to procedures; - – compilation option pragmas, especially to disable or enable runtime checks;
- –
push
andpop
pragmas to deactivate/reactivate options; - – pragmas for objects, such as
inheritable
orfinal
; - – pragmas such as
linearScanEnd
orcomputedGoto
which change the way the code is generated; - – pragmas for variables such as
register
orglobal
; - – pragmas such as
hint
to make the compiler output a message at compilation; - – pragmas such as
used
to avoid a warning message (here when a variable is not used); - –
experimental
pragma to activate experimental features; - –
deprecated
pragma to mark a type, procedure, etc. as deprecated with emission of a warning at compile time; - – pragmas to interface with other languages:
importc
,extern
,bycopy
,byref
,varargs
, etc. - – pragmas to declare the calling convention of a procedure:
nimcall
,closure
,stdcall
,cdecl
,inline
, etc. - – implementation specific pragmas:
bitsize
,align
,volatile
, etc. - - pragmas for templates such as
inject
,gensym
; - – thread pragmas;
- – pragma
pragma
which allows the users to define their own pragmas.
And here are some examples:
{.checks: off, optimization: speed.} # Checks are deactivated and code is generated for speed.
# Define a type Color as pure which implies that value names are declared in their own scope
# and may/should be accessed with their type qualifier (as Color.Red).
type Color {.pure.} = enum Red, Green, Blue
# Declare a procedure to inline if possible.
proc odd(x: int): bool {.inline.} = (x and 1) != 0
# Declaration of a C external procedure.
proc printf(formatstr: cstring) {.header: "<stdio.h>", importc: "printf", varargs.}
# Declaration of a deprecated procedure. If not used, no warning will be emitted.
proc notUsed(x: int) {.used, deprecated.} = echo x
# Declaration of a type with an alignment constraint.
type SseType = object
sseData {.align(16).}: array[4, float32]
# Declaration of a procedure containing a variable to store in register, if possible, and a variable to store as global.
proc p() =
var x {.register.}: int
var y {.global.} = "abcdef"
{.push checks: on.}
# From here, checks are activated.
...
{.pop.}
# From here, checks are deactivated again.
Perl
By convention pragmatic modules are named using lowercase letters.
- List of pragmatic modules
- diagnostics
- english
- feature
- integer
- lib
- ops
- sort
- strict
- switch
- warnings
- Utilization
Pragmatic modules have local scope and are utilized using the use directive:
use warnings; # use warnings pragma module
use strict; # use strict pragma module
To disable behaviour of a pragmatic module:
no warnings; # disable warnings pragma module
no strict; # disable strict pragma module
Phix
The following are taken directly from the Phix.syn (syntax colouring) file, which can be edited as needed (for errors or new compiler features):
Delimiters #$:.%\^
Operators , = := == != < <= > >= + - * / += -= *= /= .. & &= ? ; : | ~ .
Braces 7 ()[]{}
BlockComment /* */ --/* --*/ #[ #]
LineComment -- //
TokenStart abcedfghijklmnopqrstuvwxyz
TokenStart ABCDEFGHIJKLMNOPQRSTUVWXYZ_
TokenChar 0123456789
Escapes \rnt\'"eE#x0buU
The last line means that escapes in string literals start with a backslash, and there are 14 of them: CR, LF, TAB, backslash, single and double quotes, escape (#1B, e and E allowed), hex byte (# and x allowed), NUL, backspace, and 4 and 8-digit unicode characters. The 7 in Braces is just the number of nested colours to use.
(The above is further explained on [[Special_characters]])
The include directive causes the compiler to stop processing the current file and instead start compiling the specified file, returning to the next line when done.
The #ilASM{} directive contains inline assembly, which can contain PE/ELF/32/64 guards to control the exact code emitted, mainly for low-level system routines, such as file I/O, which are usually in builtins\VM. One day I hope/expect to add a JS guard, for pwa/p2js, but there isn't one yet.
The #isginfo{}, #isinit{}, and #istype{} directives instruct the compiler to perform various type-inference and legal value ranges checks. Primarily for compiler development use, not end user applications. No code is generated, but compilation will abort if they fail.
The with/without directives control several run-time options:
javascript -- ensure pwa/p2js compatible, ie can be run in a browser, equivalent to js and javascript_semantics
profile -- produce an execution count listing when the program terminates
profile_time -- produce an execution percentage listing when the program terminates
safe_mode -- see [[Untrusted_environment#Phix]]
type_check -- turn user-defined type checking on or off (can make it noticeably faster, once testing is done)
trace -- allow or disallow debugging (source code line-by-line tracing)
debug -- turn debugging info generation on or off
nested_globals -- fine-grained scope control, nested_locals is the complementary option
The last two are related: without debug completely removes all tracing and diagnostics for a specific file (primarily intended for use in well-tested system routines), whereas (under with debug, which is the default) with/without trace can make debugging less tedious by not stopping on every line of irrelevant (user-selected) code, although dumps still contain a full call stack. Some other options, specifically indirect_includes, inline, and digital stamps, exist solely for compatability and are completely ignored.
with/without console/gui still work but should now be replaced with a format directive:
format PE32|PE64|ELF32|ELF64 - you can also specify gui/console, subsystem version, icons and manifest files. Ignored when interpreting/transpiling.
The following are ignored by the compiler, but are respected by the source code reindent tool:
--#without reformat
--#with reformat
--#withdef (may be needed when reindenting OpenEuphoria code)
--#withtype
Note that an abort() statement at the top level will make the compiler ignore the rest of the file.
While technically code rather than a directive, the requires() builtin can hopefully avoid fruitless efforts to run something where it is simply never going to work, eg
requires(JS) --requires(WINDOWS) -- (one of only, or --requires(LINUX) -- a special combo) requires("1.0.2") requires(32) -- or 64
PicoLisp
PicoLisp makes no formal difference between any normal and "specific" operation of the language. Any possible desired effect can be achieved by calling a function or setting a variable. For example, function calls can be traced with the 'trace' function.
/* PL/I */ Section added -- Superfluous blanks suppressed
PL/I
Disabled on-conditions can be seen as pragmatic directives.
SubscriptRange (SubRg), StringRange (StRg),
StringSize (StRz), Size conditions
can be enabled for a procedure or a begin block.
By default, for optimization reasons,
SubscriptRange,StringRange,StringSize,Size are disabled.
If enabled the SubscriptRange condition is raised for out-of-bound subscript of
an array.
For example:
declare (t(100),i) fixed binary;
i=101;
t(i)=0;
will cause unpredictible results. And :
(SubscriptRange): begin;
declare (t(100),i) fixed binary;
i=101;
t(i)=0;
end;
will issue the message : "The SubscriptRange condition was raised." at execution time.
Or, it can be handle by an on-unit.
(SubscriptRange): begin;
declare (t(100),i) fixed binary;
i=101;
on SubscriptRange begin; put skip list('error on t(i)'); goto e; end;
t(i)=0;
e:on SubscriptRange system; /* default dehaviour */
end;
And the same way for a string,
the StringRange condition is raised when a substring reference is beyond
the span of the string.
And finally:
The StringSize condition is raised when a string is shorten
as a result of a convertion assigment.
The Size condition is raised when a numerical value is shorten
as a result of a convertion assigment.
PowerShell
The #Requires statement prevents a script from running unless the Windows PowerShell version, modules, snap-ins, and module and snap-in version prerequisites are met. If the prerequisites are not met, Windows PowerShell does not run the script.
You can use #Requires statements in any script. You cannot use them in functions, cmdlets, or snap-ins.
#Requires -Version <N>[.<n>]
#Requires –PSSnapin <PSSnapin-Name> [-Version <N>[.<n>]]
#Requires -Modules { <Module-Name> | <Hashtable> }
#Requires –ShellId <ShellId>
#Requires -RunAsAdministrator
For a full description:
Get-Help about_Requires
PureBasic
PureBasic supports several pragmatic directives, also known as compiler directives.
CompilerIf…CompilerElseIf…CompilerElse…CompilerEndIf
: allows certain parts of the code to be compiled depending on the evaluation of a constant expression.
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
; some Linux specific code
CompilerElse
; some code for other operating systems
CompilerEndIf
CompilerSelect…CompilerCase…CompilerDefault…CompilerEndSelect
: Allows you to select which code to compile based on a constant numeric value.
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_MacOS
; some Mac OS
CompilerCase #PB_OS_Linux
; some Linux specific code
CompilerEndSelect
CompilerError
and CompilerWarning
: generate an error or a warning, respectively.
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
CompilerError "Linux is not supported, sorry."
CompilerElse
CompilerWarning "OS supported, you can now comment me."
CompilerEndIf
EnableExplicit
and DisableExplicit1
: Enable or disable explicit mode. When enabled, all variables not explicitly declared with Define, Global, Protected, or Static will not be accepted and the compiler will generate an error.
EnableExplicit
Defines
a = 20 ; Ok, as declared with 'Define'
b = 10 ; Will raise an error here
EnableASM
and DisableASM
: Enable or disable the inline assembler. When enabled, all assembler keywords are available directly in the source code.
; x86 assembly example
Test = 10
EnableASM
MOV dword [v_Test],20
DisableASM
DebugTest ; Will be 20
It is important to note that the scope of these directives is global, that is, they affect all code after them until a directive is found that disables them or until the end of the code file.
Python
Python has the __future__ module which controls certain features:
- Python 3.2
Python 3.2 (r32:88445, Feb 20 2011, 21:30:00) [MSC v.1500 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import __future__
>>> __future__.all_feature_names
['nested_scopes', 'generators', 'division', 'absolute_import', 'with_statement', 'print_function', 'unicode_literals', 'barry_as_FLUFL']
>>>
('barry_as_FLUFL' is an April fools joke)
- Python 2.7
Python 2.7.2 (default, Jun 12 2011, 14:24:46) [MSC v.1500 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import __future__
>>> __future__.all_feature_names
['nested_scopes', 'generators', 'division', 'absolute_import', 'with_statement', 'print_function', 'unicode_literals']
>>>
Racket
Racket eschews pragmas that are specified outside of the language. However, one can view Racket's #lang mechanism as a much more powerful tool for achieving similar things. For example, normal code starts with #lang racket -- giving you a very Scheme-like language; change it to #lang typed/racket and you get a similar language that is statically typed; use #lang lazy and you get a Racket-like language that has lazy semantics; use #lang algol60 and you get something that is very different than Racket. (And of course, you can implement your own language quite easily.)
Raku
(formerly Perl 6)
The Perl 6 pragma mechanism is nearly identical to Perl 5's, piggybacking on the notation for importing modules (pragmas are distinguished by case from normal modules, which are generally of mixed case). By convention pragmas are lowercase, unless they are indicating the use of an unsafe feature, in which case they are in all caps.
use MONKEY-TYPING;
augment class Int {
method times (&what) { what() xx self } # pretend like we're Ruby
}
Unlike Perl 5, there is no use strict; pragma, however, since Perl 6 is strict by default. Importation of a pragma is lexically scoped as in Perl 5, but note that unlike in Perl 5, all importation is lexical in Perl 6, so pragmas are not special that way.
REXX
The REXX language has several pragmatic statements: ∙ NUMERIC DIGITS {nnn} ∙ NUMERIC FORM {ENGINEERING │ SCIENTIFIC} ∙ NUMERIC FUZZ {nnn} ∙ OPTIONS {xxx yyy zzz} ∙ TRACE {options} ∙ SIGNAL {ON │ OFF} LOSTDIGITS ∙ SIGNAL {ON │ OFF} NOVALUE ∙ SIGNAL {ON │ OFF} SYNTAX ∙ SIGNAL │ CALL {ON │ OFF} ERROR ∙ SIGNAL │ CALL {ON │ OFF} FAILURE ∙ SIGNAL │ CALL {ON │ OFF} HALT ∙ SIGNAL │ CALL {ON │ OFF} NOTREADY
numeric digits
The NUMERIC DIGITS nnn statement is used to specify to the REXX interpreter how many
(significant) decimal digits are to be used in calculating and storing numbers.
nnn can be an expression that evaluates to a positive integer.
If nnn is omitted, it defaults to 9.
If no numeric digits statement is used, the default is 9.
It must be greater than the (current) NUMERIC FUZZ setting.
numeric fuzz
The NUMERIC FUZZ nnn statement is used to specify to the REXX interpreter how many
decimal digits (at full precision) will be ignored while performing an arithmetic
comparison.
nnn can be an expression that evaluates to a non-negative integer.
If nnn is omitted, it defaults to 0.
If no numeric fuzz statement is used, the default for REXX programs is 0.
It must be less than the (current) NUMERIC DIGITS setting.
The result of using a positive value for FUZZ is that the REXX interpreter (temporarily) reduces
the number of NUMERIC DIGITS by the FUZZ value before an arithmetic comparison.
This means that arithmetic comparisons are performed with the precision of
DIGITS() minus FUZZ() where:
- DIGITS() is the value of numeric digits
- FUZZ() is the value of numeric fuzz
numeric form
The NUMERIC FORM statement is used to cause the REXX interpreter to use a specific form of
exponential format if the result of an arithmetic operation requires the use of exponential notation
with the current value of numeric digits.
The specification option after numeric form can be:
- ENGINEERING
- SCIENTIFIC
- (or omitted)
The default is scientific.
The option can be in upper/lower/mixed case.
If no numeric form statement is used, the default for REXX programs is scientific.
options
The OPTIONS statement is used to specify to the REXX interpreter on such matters on how to
process the source (statements), possibly (for instance) whether or not double byte character strings
are present, or possibly cause the REXX interpreter to force compliance to some particular rule or
REXX (program) coding standards.
There can be any number of options listed (or none).
Each particular REXX interpreters have their own options, so it isn't considered an error if some
option isn't supported (or recognized) by another REXX interpreter.
Some options are global in nature, others can be enabled and disabled.
Some REXX interpreters also have a way to specify certain options via the command-line
(also known as the C.L.).
trace
The TRACE statement is used to cause the REXX interpreter to turn off or on certain tracing
facilities for the REXX interpreter.
Most tracing options causes some sort of output (tracing of statements or values of clauses) to be
emitted to the console (terminal).
The output (tracing information) written to the terminal is usually quite distinctive and can be easily
recognized.
There are a number of options for the trace instruction, and they won't be explained here.
signal on lostdigits
If the REXX interpreter detects that a result of any arithmetic operation results in the loss of any
decimal digits, control branches to the label lostdigits. The label may be in mixed case.
Not all REXXes support this condition (option).
This condition is raised when the number of significant decimal digits in the result of an arithmetic
operation that would exceed the currently defined number of digits via numeric digits.
signal off lostdigits
This indicates to take the default action which is quietly ignore the condition and continue
execution of the REXX program.
signal on novalue
If the REXX interpreter detects an uninitialized variable is used in an evaluated expression, control
branches to the label novalue. The label may be in mixed case.
signal off novalue
This indicates to take the default action which is to quietly return the value of the uppercase version
of the variable name and continue execution of the REXX program.
signal on syntax
If the REXX interpreter detects a syntax error in the REXX program, (and the REXX interpreter
determines that the error can still be handled by the erroneous REXX program), control branches
to the label syntax. The label may be in mixed case.
signal off syntax
This indicates to take the default action which REXX issues an error message and terminates the
REXX program.
signal on error; call on error
If the REXX interpreter detects a non-zero return code from a host system command issued by
the REXX program, control branches to the label error. The label may be in mixed case.
signal off error; call off error
This indicates to take the default action which means the special variable RC (Return Code)
is quietly defined, and execution continues of the REXX program.
signal on failure; call on failure
If the REXX interpreter detects a failure from a host system command issued by the REXX
program, control branches to the label failure. The label may be in mixed case.
signal off failure; call off failure
This indicates to take the default action which means the special variable RC (Return Code)
is quietly defined, and execution continues of the REXX program.
signal on halt; call on halt
If the REXX interpreter detects an external interrupt is made to interrupt execution of the REXX
program, control branches to the label halt. The label may be in mixed case.
The external interrupt varies with which operating system is being used.
signal off halt; call off halt
This indicates to take the default action which normally means a message is issued and the
execution of the REXX program is terminated.
signal on notready; call on notready
If the REXX interpreter detects some kind of problem with stream I/O (this varies with each
REXX interpreter), control branches to the label notready. The label may be in mixed case.
signal off notready; call off notready
This indicates to take the default action which is to quietly resume execution of the REXX program.
Not all REXXes support this condition (option).
scope
The scope for the all the above statements (except for options), if issued in the main program,
will be in effect for all internal routines (subroutines/functions/procedures).
If the above statements are issued in an internal routine, upon return from that routine, the
original status is restored (to just before the invoke of that routine).
For external routines, the defaults are used.
RPL
Pragmatic directives are given through system flags that can bet with the SF
and CF
commands anywhere in a program.
System flags are a legacy of programmable calculators and unfortunately, which flag to set or reset for a specific directive depends on the calculator model you are using.
As an example, here are the directives controlled by flags on HP-28 models:
- LAST variable activated
- Immediate evaluation of constants (e, pi...) and functions
- length of binary words
- display and print formats
- decimal sign and object separator
- real number display format
- sound on/off
- underflow/overflow error handling
Fortunately, some of them can also be operated through language commands, such as STWS
(defines the length of binary words) or RAD
(defines radian as the trigonometric unit).
Scala
tailrec
@inline
@tailrec
Tcl
Mostly Tcl avoids anything like pragmas as they are a source of portability trouble. However, certain global variables can be set to induce non-standard behaviors:
- tcl_precision
- This is used to control how Tcl converts floating point numbers to strings, and represents the number of significant figures to use. From Tcl 8.5 onwards this should be left at its default (which uses the minimum number of digits required to represent the number exactly on conversion back to a double-precision float) and the
format
command used where an exact number of digits is required. - tcl_traceCompile
- This is used (provided it is enabled at library-build time) to enable printing out information about the compilation of Tcl scripts to bytecodes. (Not useful in wish on Windows due to system issues.)
- tcl_traceExec
- This is used (provided it is enabled at library-build time) to enable printing out information about the execution of Tcl's bytecodes and when different procedures are called. (Not useful in wish on Windows due to system issues.)
- tcl_interactive
- This marks whether the “convenience” features of the top-level REPL should be enabled; in non-interactive mode, Tcl scripts typically don't prompt for commands to execute, never allow abbreviation of command names, never automatically run external commands, etc.
Under normal circumstances, all of these variables should be left alone; their default values are virtually always correct for programs.
UNIX Shell
- List of pragmatic directives
- -v output the script line before it is executed
- -x output the command line arguments
- Utilization
Pragmatic directives remain effective, until they are deactivated, or the end of the script is reached:
set -vx # Activate both script line output and command line arguments pragma
set +vx # Deactivate both pragmatic directives
Wren
The closest thing Wren has to a pragmatic directive is its import statement which loads a module, executes its source code and imports variable names from that module into the current scope.
Import statements can appear anywhere a variable declaration is allowed and in particular within conditional structures. This enables us to do things such as the following:
/* windows.wren */
class Windows {
static message { "Using Windows" }
static lineSeparator { "\\r\\n" }
}
/* linux.wren */
class Linux {
static message { "Using Linux" }
static lineSeparator { "\\n" }
}
/* Pragmatic_directives.wren */
import "os" for Platform
var os
if (Platform.isWindows) {
import "./windows" for Windows
os = Windows
} else {
import "./linux" for Linux
os = Linux
}
System.print("%(os.message) which has a \"%(os.lineSeparator)\" line separator.")
- Output:
From the last script, when run on a Linux system.
$ wren_cli Pragmatic_directives.wren Using Linux which has a "\n" line separator.
XPL0
XPL0 has a single compiler directive called "string." It changes the way text strings are terminated.
Originally, strings were terminated by setting the most significant bit set on the last character. This conserved memory on early personal computers such as the Apple II by making strings one byte shorter than if they were terminated by a zero byte. As computer memory grew, this method became less desirable. It prevented using the extended character codes 128 through 255 in strings, and it prevented null strings ("").
The RawText intrinsic was added as an alternative to the Text intrinsic that enabled extended characters to be displayed in strings. It relied on a final space character added by the programmer that had its high bit set ($A0) and was not displayed.
To make XPL0 more consistent with programming standards, in 2012 the "string" directive was added.
string 0; \makes all following strings in the code zero-terminated string 1; \(or any non-zero argument) reverts to MSB termination
- Programming Tasks
- Solutions by Programming Task
- Pragmatic directives
- 6502 Assembly
- 8086 Assembly
- Ada
- ALGOL 68
- BASIC
- IS-BASIC
- QBasic
- C
- Common Lisp
- Delphi
- D
- Erlang
- Factor
- FreeBASIC
- Go
- Icon
- Unicon
- J
- Java
- Jq
- Julia
- Kotlin
- Lua
- Mathematica
- Wolfram Language
- NetRexx
- Nim
- Perl
- Phix
- PicoLisp
- PL/I
- PowerShell
- PureBasic
- Python
- Racket
- Raku
- REXX
- RPL
- Scala
- Tcl
- UNIX Shell
- Wren
- XPL0
- AWK/Omit
- ZX Spectrum Basic/Omit