X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fnasal%2Fcodegen.c;h=495456a6cf91b72a8901b52742027983dfe96e61;hb=9aa5c3b2ae9442a9f777088cae982aef9034183c;hp=8636fbb958e0f90c8fe3132629d429c69d8cbabe;hpb=a2e25e7940d2061c0a9298f4ef8347c6f174d42d;p=simgear.git diff --git a/simgear/nasal/codegen.c b/simgear/nasal/codegen.c index 8636fbb9..495456a6 100644 --- a/simgear/nasal/codegen.c +++ b/simgear/nasal/codegen.c @@ -7,6 +7,7 @@ // These are more sensical predicate names in most contexts in this file #define LEFT(tok) ((tok)->children) #define RIGHT(tok) ((tok)->lastChild) +#define UNARY(tok) (LEFT(tok) && LEFT(tok) == RIGHT(tok)) #define BINARY(tok) (LEFT(tok) && RIGHT(tok) && LEFT(tok)->next == RIGHT(tok)) // Forward references for recursion @@ -165,6 +166,15 @@ static int defArg(struct Parser* p, struct Token* t) RIGHT(t)->num *= -1; return defArg(p, RIGHT(t)); } + if(t->type == TOK_CAT && RIGHT(t) && + RIGHT(t)->type == TOK_LITERAL && !RIGHT(t)->str) + { + /* default arguments are constants, but "~1" parses as two + * tokens, so we have to subset the expression generator for that + * case */ + RIGHT(t)->num = ~(int)RIGHT(t)->num; + return defArg(p, RIGHT(t)); + } return findConstantIndex(p, t); } @@ -634,12 +644,16 @@ static void genExpr(struct Parser* p, struct Token* t) else genExpr(p, LEFT(t)); break; case TOK_LBRA: - if(BINARY(t)) { - genExtract(p, t); - } else { + if(UNARY(t)) { emit(p, OP_NEWVEC); genList(p, LEFT(t), 1); } + else if(BINARY(t)) { + genExtract(p, t); + } else { + // forbid usage as 'vec[]' + naParseError(p, "missing index or slice expression(s)", t->line); + } break; case TOK_LCURL: emit(p, OP_NEWHASH); @@ -673,6 +687,21 @@ static void genExpr(struct Parser* p, struct Token* t) genExpr(p, RIGHT(t)); // unary negation (see also TOK_MINUS!) emit(p, OP_NEG); break; + case TOK_CAT: + if(BINARY(t)) { + genBinOp(OP_CAT, p, t); // string concatenation + } else if(RIGHT(t) && RIGHT(t)->type == TOK_LITERAL && !RIGHT(t)->str) { + RIGHT(t)->num = ~(int)RIGHT(t)->num; // Pre-negate constants + genScalarConstant(p, RIGHT(t)); + } else { + genExpr(p, RIGHT(t)); // unary, bitwise negation + emit(p, OP_BIT_NEG); + } + break; + case TOK_BIT_NEG: + genExpr(p, RIGHT(t)); // unary, bitwise negation (see also TOK_CAT!) + emit(p, OP_BIT_NEG); + break; case TOK_DOT: genExpr(p, LEFT(t)); if(!RIGHT(t) || RIGHT(t)->type != TOK_SYMBOL) @@ -685,10 +714,12 @@ static void genExpr(struct Parser* p, struct Token* t) case TOK_AND: case TOK_OR: genShortCircuit(p, t); break; + case TOK_BIT_AND:genBinOp(OP_BIT_AND, p, t); break; + case TOK_BIT_OR: genBinOp(OP_BIT_OR, p, t); break; + case TOK_BIT_XOR:genBinOp(OP_BIT_XOR, p, t); break; case TOK_MUL: genBinOp(OP_MUL, p, t); break; case TOK_PLUS: genBinOp(OP_PLUS, p, t); break; case TOK_DIV: genBinOp(OP_DIV, p, t); break; - case TOK_CAT: genBinOp(OP_CAT, p, t); break; case TOK_LT: genBinOp(OP_LT, p, t); break; case TOK_LTE: genBinOp(OP_LTE, p, t); break; case TOK_EQ: genBinOp(OP_EQ, p, t); break; @@ -700,6 +731,9 @@ static void genExpr(struct Parser* p, struct Token* t) case TOK_MULEQ: genEqOp(OP_MUL, p, t); break; case TOK_DIVEQ: genEqOp(OP_DIV, p, t); break; case TOK_CATEQ: genEqOp(OP_CAT, p, t); break; + case TOK_BIT_ANDEQ: genEqOp(OP_BIT_AND, p, t); break; + case TOK_BIT_OREQ: genEqOp(OP_BIT_OR, p, t); break; + case TOK_BIT_XOREQ: genEqOp(OP_BIT_XOR, p, t); break; default: naParseError(p, "parse error", t->line); };