2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* Structures and functions for interpreting a parse tree. The interpreter
|
|
|
|
* traverses a parse tree in a depth-first manner, interpreting each node it
|
|
|
|
* reaches along the way. This is the last stage of the processing of a source
|
|
|
|
* code file.
|
|
|
|
*
|
|
|
|
* \file interpreter.h
|
|
|
|
*
|
|
|
|
* \author Justin J. Meza
|
|
|
|
*
|
|
|
|
* \date 2010-2011
|
|
|
|
*/
|
2010-08-09 07:01:59 +00:00
|
|
|
|
|
|
|
#ifndef __INTERPRETER_H__
|
|
|
|
#define __INTERPRETER_H__
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#include "parser.h"
|
|
|
|
#include "unicode.h"
|
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* Retrieves a value's integer data.
|
|
|
|
*/
|
2010-08-09 07:01:59 +00:00
|
|
|
#define getInteger(value) (value->data.i)
|
2011-06-15 06:54:12 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves a value's decimal data.
|
|
|
|
*/
|
2010-08-09 07:01:59 +00:00
|
|
|
#define getFloat(value) (value->data.f)
|
2011-06-15 06:54:12 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves a value's string data.
|
|
|
|
*/
|
2010-08-09 07:01:59 +00:00
|
|
|
#define getString(value) (value->data.s)
|
2011-06-15 06:54:12 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves a value's function data.
|
|
|
|
*/
|
2010-11-16 05:25:51 +00:00
|
|
|
#define getFunction(value) (value->data.fn)
|
2010-08-09 07:01:59 +00:00
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* Retrieves a value's array data.
|
|
|
|
*/
|
|
|
|
#define getArray(value) (value->data.a)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Represents a value type.
|
|
|
|
*/
|
2010-08-09 07:01:59 +00:00
|
|
|
typedef enum {
|
|
|
|
VT_INTEGER, /**< An integer value. */
|
2011-06-15 06:54:12 +00:00
|
|
|
VT_FLOAT, /**< A decimal value. */
|
|
|
|
VT_BOOLEAN, /**< A boolean value. */
|
|
|
|
VT_STRING, /**< A string value. */
|
2010-11-16 05:25:51 +00:00
|
|
|
VT_NIL, /**< Represents no value. */
|
2011-06-15 06:54:12 +00:00
|
|
|
VT_FUNC, /**< A function. */
|
|
|
|
VT_ARRAY /**< An array. */
|
2010-08-09 07:01:59 +00:00
|
|
|
} ValueType;
|
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* Stores value data.
|
|
|
|
*/
|
2010-08-09 07:01:59 +00:00
|
|
|
typedef union {
|
2011-06-15 06:54:12 +00:00
|
|
|
int i; /**< Integer data. */
|
|
|
|
float f; /**< Decimal data. */
|
|
|
|
char *s; /**< String data. */
|
|
|
|
FuncDefStmtNode *fn; /**< Function data. */
|
|
|
|
struct scopeobject *a; /**< Array data. */
|
2010-08-09 07:01:59 +00:00
|
|
|
} ValueData;
|
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* Increments a value's semaphore.
|
|
|
|
*/
|
2010-08-09 07:01:59 +00:00
|
|
|
#define V(value) (value->semaphore++)
|
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* Decrements a value's semaphore.
|
|
|
|
*/
|
2010-08-09 07:01:59 +00:00
|
|
|
#define P(value) (value->semaphore--)
|
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* Stores a value.
|
|
|
|
*/
|
2010-08-09 07:01:59 +00:00
|
|
|
typedef struct {
|
|
|
|
ValueType type; /**< The type of value stored. */
|
2011-06-15 06:54:12 +00:00
|
|
|
ValueData data; /**< The value data. */
|
2010-08-09 07:01:59 +00:00
|
|
|
unsigned short semaphore; /**< A semaphore for value usage. */
|
|
|
|
} ValueObject;
|
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* Represents the return type.
|
|
|
|
*/
|
2010-08-09 07:01:59 +00:00
|
|
|
typedef enum {
|
2011-06-15 06:54:12 +00:00
|
|
|
RT_DEFAULT, /**< Code block completed successfully. */
|
|
|
|
RT_BREAK, /**< Broke out of a loop or switch statement. */
|
|
|
|
RT_RETURN /**< Returned from a function. */
|
2010-08-09 07:01:59 +00:00
|
|
|
} ReturnType;
|
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* Stores return state.
|
|
|
|
*/
|
2010-08-09 07:01:59 +00:00
|
|
|
typedef struct {
|
|
|
|
ReturnType type; /**< The type of return encountered. */
|
|
|
|
ValueObject *value; /**< The optional return value. */
|
|
|
|
} ReturnObject;
|
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* Stores a set of variables hierarchically.
|
|
|
|
*/
|
2010-08-09 07:01:59 +00:00
|
|
|
typedef struct scopeobject {
|
2011-06-15 06:54:12 +00:00
|
|
|
struct scopeobject *parent; /**< The parent scope. */
|
2011-07-19 07:02:43 +00:00
|
|
|
struct scopeobject *caller; /**< The caller scope (if in a function). */
|
2011-06-15 06:54:12 +00:00
|
|
|
ValueObject *impvar; /**< The \ref impvar "implicit variable". */
|
|
|
|
unsigned int numvals; /**< The number of values in the scope. */
|
|
|
|
char **names; /**< The names of the values. */
|
|
|
|
ValueObject **values; /**< The values in the scope. */
|
2010-08-09 07:01:59 +00:00
|
|
|
} ScopeObject;
|
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* \name Utilities
|
|
|
|
*
|
|
|
|
* Functions for performing helper tasks.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
|
|
|
void printInterpreterError(const char *, IdentifierNode *, ScopeObject *);
|
|
|
|
char *copyString(char *);
|
|
|
|
unsigned int isDecString(const char *);
|
|
|
|
unsigned int isHexString(const char *);
|
|
|
|
char *resolveIdentifierName(IdentifierNode *, ScopeObject *);
|
|
|
|
/**@}*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \name Value object modifiers
|
|
|
|
*
|
|
|
|
* Functions for creating, copying, and deleting value objects.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ValueObject *createNilValueObject(void);
|
|
|
|
ValueObject *createBooleanValueObject(int);
|
|
|
|
ValueObject *createIntegerValueObject(int);
|
|
|
|
ValueObject *createFloatValueObject(float);
|
|
|
|
ValueObject *createStringValueObject(char *);
|
2010-11-16 05:25:51 +00:00
|
|
|
ValueObject *createFunctionValueObject(FuncDefStmtNode *);
|
2011-06-15 06:54:12 +00:00
|
|
|
ValueObject *createArrayValueObject(ScopeObject *);
|
2010-08-09 07:01:59 +00:00
|
|
|
ValueObject *copyValueObject(ValueObject *);
|
|
|
|
void deleteValueObject(ValueObject *);
|
2011-06-15 06:54:12 +00:00
|
|
|
/**@}*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \name Scope object modifiers
|
|
|
|
*
|
|
|
|
* Functions for manipulating scope objects and their data.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ScopeObject *createScopeObject(ScopeObject *);
|
2011-07-19 07:02:43 +00:00
|
|
|
ScopeObject *createScopeObjectCaller(ScopeObject *, ScopeObject *);
|
2010-08-09 07:01:59 +00:00
|
|
|
void deleteScopeObject(ScopeObject *);
|
2011-06-15 06:54:12 +00:00
|
|
|
ValueObject *createScopeValue(ScopeObject *, ScopeObject *, IdentifierNode *);
|
|
|
|
ValueObject *updateScopeValue(ScopeObject *, ScopeObject *, IdentifierNode *, ValueObject *);
|
|
|
|
ValueObject *getScopeValue(ScopeObject *, ScopeObject *, IdentifierNode *);
|
|
|
|
ValueObject *getScopeValueLocal(ScopeObject *, ScopeObject *, IdentifierNode *);
|
|
|
|
ScopeObject *getScopeObject(ScopeObject *, ScopeObject *, IdentifierNode *);
|
2011-07-19 07:02:43 +00:00
|
|
|
ScopeObject *getScopeObjectLocal(ScopeObject *, ScopeObject *, IdentifierNode *);
|
2011-06-15 06:54:12 +00:00
|
|
|
void deleteScopeValue(ScopeObject *, ScopeObject *, IdentifierNode *);
|
|
|
|
/**@}*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \name Return object modifiers
|
|
|
|
*
|
|
|
|
* Functions for creating and deleting return objects.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
|
|
|
ReturnObject *createReturnObject(ReturnType, ValueObject *);
|
|
|
|
void deleteReturnObject(ReturnObject *);
|
|
|
|
/**@}*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \name Casts
|
|
|
|
*
|
|
|
|
* Functions for performing casts between different types of values.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ValueObject *castBooleanImplicit(ValueObject *, ScopeObject *);
|
|
|
|
ValueObject *castIntegerImplicit(ValueObject *, ScopeObject *);
|
|
|
|
ValueObject *castFloatImplicit(ValueObject *, ScopeObject *);
|
|
|
|
ValueObject *castStringImplicit(ValueObject *, ScopeObject *);
|
2011-06-15 06:54:12 +00:00
|
|
|
ValueObject *castBooleanExplicit(ValueObject *, ScopeObject *);
|
|
|
|
ValueObject *castIntegerExplicit(ValueObject *, ScopeObject *);
|
|
|
|
ValueObject *castFloatExplicit(ValueObject *, ScopeObject *);
|
|
|
|
ValueObject *castStringExplicit(ValueObject *, ScopeObject *);
|
|
|
|
/**@}*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \name Node interpreters
|
|
|
|
*
|
|
|
|
* Functions for interpreting basic parse tree nodes.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ValueObject *interpretExprNode(ExprNode *, ScopeObject *);
|
|
|
|
ReturnObject *interpretStmtNode(StmtNode *, ScopeObject *);
|
|
|
|
ReturnObject *interpretStmtNodeList(StmtNodeList *, ScopeObject *);
|
|
|
|
ReturnObject *interpretBlockNode(BlockNode *, ScopeObject *);
|
|
|
|
int interpretMainNode(MainNode *);
|
2011-06-15 06:54:12 +00:00
|
|
|
/**@}*/
|
2010-08-09 07:01:59 +00:00
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* \name Expression interpreters
|
|
|
|
*
|
|
|
|
* Functions for interpreting expression parse tree nodes.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ValueObject *interpretImpVarExprNode(ExprNode *, ScopeObject *);
|
|
|
|
ValueObject *interpretCastExprNode(ExprNode *, ScopeObject *);
|
|
|
|
ValueObject *interpretFuncCallExprNode(ExprNode *, ScopeObject *);
|
|
|
|
ValueObject *interpretIdentifierExprNode(ExprNode *, ScopeObject *);
|
|
|
|
ValueObject *interpretConstantExprNode(ExprNode *, ScopeObject *);
|
2011-06-15 06:54:12 +00:00
|
|
|
/**@}*/
|
2010-08-09 07:01:59 +00:00
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* \name Operation interpreters
|
|
|
|
*
|
|
|
|
* Functions for interpreting operation parse tree nodes.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ValueObject *interpretNotOpExprNode(OpExprNode *, ScopeObject *);
|
|
|
|
ValueObject *interpretArithOpExprNode(OpExprNode *, ScopeObject *);
|
|
|
|
ValueObject *interpretBoolOpExprNode(OpExprNode *, ScopeObject *);
|
|
|
|
ValueObject *interpretEqualityOpExprNode(OpExprNode *, ScopeObject *);
|
|
|
|
ValueObject *interpretConcatOpExprNode(OpExprNode *, ScopeObject *);
|
|
|
|
ValueObject *interpretOpExprNode(ExprNode *, ScopeObject *);
|
2011-06-15 06:54:12 +00:00
|
|
|
/**@}*/
|
2010-08-09 07:01:59 +00:00
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* \name Statement interpreters
|
|
|
|
*
|
|
|
|
* Functions for interpreting statement parse tree nodes.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ReturnObject *interpretCastStmtNode(StmtNode *, ScopeObject *);
|
|
|
|
ReturnObject *interpretPrintStmtNode(StmtNode *, ScopeObject *);
|
|
|
|
ReturnObject *interpretInputStmtNode(StmtNode *, ScopeObject *);
|
|
|
|
ReturnObject *interpretAssignmentStmtNode(StmtNode *, ScopeObject *);
|
|
|
|
ReturnObject *interpretDeclarationStmtNode(StmtNode *, ScopeObject *);
|
|
|
|
ReturnObject *interpretIfThenElseStmtNode(StmtNode *, ScopeObject *);
|
|
|
|
ReturnObject *interpretSwitchStmtNode(StmtNode *, ScopeObject *);
|
|
|
|
ReturnObject *interpretBreakStmtNode(StmtNode *, ScopeObject *);
|
|
|
|
ReturnObject *interpretReturnStmtNode(StmtNode *, ScopeObject *);
|
|
|
|
ReturnObject *interpretLoopStmtNode(StmtNode *, ScopeObject *);
|
2010-11-16 06:12:08 +00:00
|
|
|
ReturnObject *interpretDeallocationStmtNode(StmtNode *, ScopeObject *);
|
2010-08-09 07:01:59 +00:00
|
|
|
ReturnObject *interpretFuncDefStmtNode(StmtNode *, ScopeObject *);
|
|
|
|
ReturnObject *interpretExprStmtNode(StmtNode *, ScopeObject *);
|
2011-06-15 06:54:12 +00:00
|
|
|
/**@}*/
|
2010-08-09 07:01:59 +00:00
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* \name Arithmetic operations (integer-integer)
|
|
|
|
*
|
|
|
|
* Functions for performing integer-integer operations on values.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ValueObject *opAddIntegerInteger(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opSubIntegerInteger(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opMultIntegerInteger(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opDivIntegerInteger(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opMaxIntegerInteger(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opMinIntegerInteger(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opModIntegerInteger(ValueObject *, ValueObject *);
|
2011-06-15 06:54:12 +00:00
|
|
|
/**@}*/
|
2010-08-09 07:01:59 +00:00
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* \name Arithmetic operations (integer-float)
|
|
|
|
*
|
|
|
|
* Functions for performing integer-float operations on values.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ValueObject *opAddIntegerFloat(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opSubIntegerFloat(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opMultIntegerFloat(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opDivIntegerFloat(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opMaxIntegerFloat(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opMinIntegerFloat(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opModIntegerFloat(ValueObject *, ValueObject *);
|
2011-06-15 06:54:12 +00:00
|
|
|
/**@}*/
|
2010-08-09 07:01:59 +00:00
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* \name Arithmetic operations (float-integer)
|
|
|
|
*
|
|
|
|
* Functions for performing float-integer operations on values.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ValueObject *opAddFloatInteger(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opSubFloatInteger(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opMultFloatInteger(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opDivFloatInteger(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opMaxFloatInteger(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opMinFloatInteger(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opModFloatInteger(ValueObject *, ValueObject *);
|
2011-06-15 06:54:12 +00:00
|
|
|
/**@}*/
|
2010-08-09 07:01:59 +00:00
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* \name Arithmetic operations (float-float)
|
|
|
|
*
|
|
|
|
* Functions for performing float-float operations on values.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ValueObject *opAddFloatFloat(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opSubFloatFloat(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opMultFloatFloat(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opDivFloatFloat(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opMaxFloatFloat(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opMinFloatFloat(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opModFloatFloat(ValueObject *, ValueObject *);
|
2011-06-15 06:54:12 +00:00
|
|
|
/**@}*/
|
2010-08-09 07:01:59 +00:00
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* \name Equality operations (boolean-boolean)
|
|
|
|
*
|
|
|
|
* Functions for performing boolean-boolean operations on values.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ValueObject *opEqBooleanBoolean(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opNeqBooleanBoolean(ValueObject *, ValueObject *);
|
2011-06-15 06:54:12 +00:00
|
|
|
/**@}*/
|
2010-08-09 07:01:59 +00:00
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* \name Equality operations (integer-integer)
|
|
|
|
*
|
|
|
|
* Functions for performing integer-integer operations on values.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ValueObject *opEqIntegerInteger(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opNeqIntegerInteger(ValueObject *, ValueObject *);
|
2011-06-15 06:54:12 +00:00
|
|
|
/**@}*/
|
2010-08-09 07:01:59 +00:00
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* \name Equality operations (integer-float)
|
|
|
|
*
|
|
|
|
* Functions for performing integer-float operations on values.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ValueObject *opEqIntegerFloat(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opNeqIntegerFloat(ValueObject *, ValueObject *);
|
2011-06-15 06:54:12 +00:00
|
|
|
/**@}*/
|
2010-08-09 07:01:59 +00:00
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* \name Equality operations (float-integer)
|
|
|
|
*
|
|
|
|
* Functions for performing float-integer operations on values.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ValueObject *opEqFloatInteger(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opNeqFloatInteger(ValueObject *, ValueObject *);
|
2011-06-15 06:54:12 +00:00
|
|
|
/**@}*/
|
2010-08-09 07:01:59 +00:00
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* \name Equality operations (float-float)
|
|
|
|
*
|
|
|
|
* Functions for performing float-float operations on values.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ValueObject *opEqFloatFloat(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opNeqFloatFloat(ValueObject *, ValueObject *);
|
2011-06-15 06:54:12 +00:00
|
|
|
/**@}*/
|
2010-08-09 07:01:59 +00:00
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* \name Equality operations (string-string)
|
|
|
|
*
|
|
|
|
* Functions for performing string-string operations on values.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ValueObject *opEqStringString(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opNeqStringString(ValueObject *, ValueObject *);
|
2011-06-15 06:54:12 +00:00
|
|
|
/**@}*/
|
2010-08-09 07:01:59 +00:00
|
|
|
|
2011-06-15 06:54:12 +00:00
|
|
|
/**
|
|
|
|
* \name Equality operations (nil-nil)
|
|
|
|
*
|
|
|
|
* Functions for performing nil-nil operations on values.
|
|
|
|
*/
|
|
|
|
/**@{*/
|
2010-08-09 07:01:59 +00:00
|
|
|
ValueObject *opEqNilNil(ValueObject *, ValueObject *);
|
|
|
|
ValueObject *opNeqNilNil(ValueObject *, ValueObject *);
|
2011-06-15 06:54:12 +00:00
|
|
|
/**@}*/
|
2010-08-09 07:01:59 +00:00
|
|
|
|
|
|
|
#endif /* __INTERPRETER_H__ */
|