Files
simgear/simgear/nasal/parse.h
T
andy dd1ea541ec Sync with Nasal upstream (Melchior already had a chance to test this,
so hopefully not too much breaks).  New syntax features:

1. Call-by-name function arguments.  You can specify a hash literal in
place of ordered function arguments, and it will become the local
variable namespace for the called function, making functions with many
arguments more readable.  Ex:

   view_manager.lookat(heading:180, pitch:20, roll:0, x:X0, y:Y0, z:Z0,
                       time:now, fov:55);

Declared arguments are checked and defaulted as would be expected:
it's an error if you fail to pass a value for an undefaulted argument,
missing default arguments get assigned, and any rest parameter
(e.g. "func(a,b=2,rest...){}") will be assigned with an empty vector.

2. Vector slicing.  Vectors (lists) can now be created from others
using an ordered list of indexes and ranges.  For example:

   var v1 = ["a","b","c","d","e"]

   var v2 = v1[3,2];   # == ["d","c"];
   var v3 = v1[1:3];   # i.e. range from 1 to 3: ["b","c","d"];
   var v4 = v1[1:];    # no value means "to the end": ["b","c","d","e"]
   var i = 2;
   var v5 = v1[i];     # runtime expressions are fine: ["c"]
   var v6 = v1[-2,-1]; # negative indexes are relative to end: ["d","e"]

The range values can be computed at runtime (e.g. i=1; v5=v1[i:]).
Negative indices work the same way the do with the vector functions
(-1 is the last element, -2 is 2nd to last, etc...).

3. Multi-assignment expressions.  You can assign more than one
variable (or lvalue) at a time by putting them in a parenthesized
list:

   (var a, var b) = (1, 2);
   var (a, b) = (1, 2);               # Shorthand for (var a, var b)
   (var a, v[0], obj.field) = (1,2,3) # Any assignable lvalue works

   var color = [1, 1, 0.5];
   var (r, g, b) = color;  # works with runtime vectors too
2008-09-26 18:22:12 +00:00

113 lines
2.6 KiB
C

#ifndef _PARSE_H
#define _PARSE_H
#include <setjmp.h>
#include "nasal.h"
#include "data.h"
#include "code.h"
enum tok {
TOK_TOP=1, TOK_AND, TOK_OR, TOK_NOT, TOK_LPAR, TOK_RPAR, TOK_LBRA,
TOK_RBRA, TOK_LCURL, TOK_RCURL, TOK_MUL, TOK_PLUS, TOK_MINUS, TOK_NEG,
TOK_DIV, TOK_CAT, TOK_COLON, TOK_DOT, TOK_COMMA, TOK_SEMI,
TOK_ASSIGN, TOK_LT, TOK_LTE, TOK_EQ, TOK_NEQ, TOK_GT, TOK_GTE,
TOK_IF, TOK_ELSIF, TOK_ELSE, TOK_FOR, TOK_FOREACH, TOK_WHILE,
TOK_RETURN, TOK_BREAK, TOK_CONTINUE, TOK_FUNC, TOK_SYMBOL,
TOK_LITERAL, TOK_EMPTY, TOK_NIL, TOK_ELLIPSIS, TOK_QUESTION, TOK_VAR,
TOK_PLUSEQ, TOK_MINUSEQ, TOK_MULEQ, TOK_DIVEQ, TOK_CATEQ,
TOK_FORINDEX
};
// Precedence rules
enum { PREC_BINARY=1, PREC_REVERSE, PREC_PREFIX, PREC_SUFFIX };
struct Token {
enum tok type;
int line;
char* str;
int strlen;
int rule;
double num;
struct Token* next;
struct Token* prev;
struct Token* children;
struct Token* lastChild;
};
struct Parser {
// Handle to the Nasal interpreter
struct Context* context;
char* err;
int errLine;
jmp_buf jumpHandle;
// The parse tree ubernode
struct Token tree;
// The input buffer
char* buf;
int len;
// Input file parameters (for generating pretty stack dumps)
naRef srcFile;
int firstLine;
// Chunk allocator. Throw away after parsing.
void** chunks;
int* chunkSizes;
int nChunks;
int leftInChunk;
// Computed line number table for the lexer
int* lines;
int nLines;
struct CodeGenerator* cg;
};
struct CodeGenerator {
int lastLine;
// Accumulated byte code array
unsigned short* byteCode;
int codesz;
int codeAlloced;
// Inst. -> line table, stores pairs of {ip, line}
unsigned short* lineIps;
int nLineIps; // number of pairs
int nextLineIp;
int* argSyms;
int* optArgSyms;
int* optArgVals;
naRef restArgSym;
// Stack of "loop" frames for break/continue statements
struct {
int breakIP;
int contIP;
struct Token* label;
} loops[MAX_MARK_DEPTH];
int loopTop;
// Dynamic storage for constants, to be compiled into a static table
naRef consts;
};
void naParseError(struct Parser* p, char* msg, int line);
void naParseInit(struct Parser* p);
void* naParseAlloc(struct Parser* p, int bytes);
void naParseDestroy(struct Parser* p);
void naLex(struct Parser* p);
int naLexUtf8C(char* s, int len, int* used); /* in utf8lib.c */
naRef naCodeGen(struct Parser* p, struct Token* block, struct Token* arglist);
void naParse(struct Parser* p);
#endif // _PARSE_H