Joy Online Manual

Preprocessor Features

Table of Contents

Introduction
Macros
Header Files
Conditional Compilation
Miscellaneous Features


Introduction

Joy adds some features of the C preprocessor to JavaScript. While in C the preprocessor is an indepent program operating prior to compilation, the Joy "preprocessor" is built into the lexical analysis stage of the JavaScript interpreter. Joy imposes a number of restrictions on preprocessor use compared with C, some of which might be lifted in future releases.



Macros

NAME

#define - Define a macro
#undef - Undefine a macro

SYNOPSIS

#define macro [expansion]
#define macro(arg1, arg2, ...) [expansion]
#undef macro

DESCRIPTION
You can define macro constants and even macros with arguments. For the macro to be usable by Joy, it has to expand to a syntactically correct Joy expression. So you cannot define "synonyms" for language keywords (e.g. #define EXTERN extern), as is common practice in C. Macros with arguments are treated as JavaScript function definitions. This means that "statement" macros, or macros that use symbols from the lexical scope of their caller, won't work in Joy.

Because C header files tend to define zillions of macros of which only a few are ever used, the right hand side is compiled and evaluated lazily on the first reference to the macro (error messages will contain the file name and line number of the definition, though).

EXAMPLES

js> #define MAX(x,y) x > y ? x : y
js> MAX(3,4)
4
js> MAX

function MAX(x, y) {
return x > y ? x : y;
pointer

Joy Online Manual

NAME
Pointer - Represents a pointer or C array

DESCRIPTION
Both C pointers and arrays are reflected to JavaScript as objects of the Pointer type. Pointer objects are created automatically by Joy whenever a pointer or array needs to be passed to JavaScript (as a return value or from a variable access). Another way to create Pointer objects is by using the Joy address operator &, or a type cast. Joy can manipulate pointers to any type, including function pointers, and pointers to arrays.

You can dereference pointers using the * operator, as in C. You can use pointer arithmetic exactly as in C.

Passing JavaScript functions as function pointers (i.e., JavaScript call back functions) is not yet supported. Calling out to C via function pointers works, though.

PROPERTIES
Like in C, you can access the data value at the pointer location by writing pointer[0]. In fact, this is what the * operator compiles to. You can also use pointer[index] to access other memory locations (the index will be multiplied with the aligned size of the pointer base type and used as an offset, like in C). Pointer objects that represent arrays will report a JavaScript error if you try to write to an index that falls outside of the array.

Index
ng through the above mentioned paths, Joy will look in the directories %HOMEPATH%\Library\Joy\PrecompiledHeaders, %NEXT_ROOT%\Local\Library\Joy\PrecompiledHeaders, and then %NEXT_ROOT%\Network\Library\Joy\PrecompiledHeaders for file with its extension replaced by .jp. Such files load much faster and the symbols and declarations they contain will be resolved lazily on demand, so no memory is wasted on header file contents that you do not use.

Every Joy interpreter will automatically import the file itkDefaultHeaders.jp, which is a resource of the itkRuntime.framework, on startup. That file will contain at least the whole AppKit.h as well as prototypes for the ANSI-C library; see the source file itkDefaultHeaders.h (in the same resources folder) if you are interested in the exact contents for your platform.


Conditional Compilation

NAME

#if - Compile code if condition is true
#ifdef - Compile code if macro is defined
#ifndef - Compile code if macro is not defined
#else - Compile if previous condition was false
#elif - Compile if previous condition was false and new condition is true
#endif - End conditional compilation

SYNOPSIS

#if expr
#ifdef macro
#ifndef macro
#else
#elif expr
#endif

DESCRIPTION
Because Joy JavaScript uses a byte-code compiler, it does make sense to speak of conditional compilation, though Joy is an interpreted language.

The most interesting use for conditional compilation in Joy is to create a single source file that can both be compiled by the Objective-C compiler and sourced into a Joy interpreter! Also, if a future version of Joy adds some new syntax that would not compile in the earlier version, you can use preprocessor conditionals to maintain backward compatibility.

All conditionals work as they do in C. An exception is that you can only use defined(macro) in #if expressions, but not  defined macro, which would be a legal alternative in the C preprocessor.

Because every Joy interpreter defines a macro __JOY__, which expands into the numerical version number as returned from the version function, you can place code which should only be seen by the Joy interpreter within #ifdef __JOY__ ... #endif, and code which should be seen only by the Objective-C compiler within #ifndef __JOY__ ... #endif.

EXAMPLE

js> #ifdef __JOY__
static NSRect r = [[1,2],[3,4]]
#else
static NSRect r = {{1,2},{3,4}};
#endif


Miscellaneous Features

NAME

#error - Emit compilation error
#warning - Emit compilation warning
#pragma - Set compiler-specific option

SYNOPSIS

#error line
#warning line
#pragma line

DESCRIPTION
The #error and #warning directives work like they do in the C preprocessor. The #pragma directive is currently ignored and produces a warning message.

EXAMPLE

js> #ifdef __JOY__
name = name.replace(/(\w+)\s(\w+)/, "$2, $1")
#else
#warning "Regular expressions not supported in Objective-C"
#endif


Index