Skip to content

Commit

Permalink
implemented bitwise operators
Browse files Browse the repository at this point in the history
  • Loading branch information
AnonymousAAArdvark committed Dec 3, 2022
1 parent 7a585c2 commit a580f38
Show file tree
Hide file tree
Showing 186 changed files with 3,713 additions and 3,601 deletions.
2 changes: 1 addition & 1 deletion docs/zh-cn/string.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"·t" // 选项卡。
"·v" // 垂直制表符。
```
> 有关转义序列的更多信息,请参考 [这篇文章](https://en.wikipedia.org/wiki/Escape_sequences_in_C)。
> 有关转义序列的更多信息,请参考 [这篇文章]( https://en.wikipedia.org/wiki/Escape_sequences_in_C )。
## 静态方法
Expand Down
6 changes: 6 additions & 0 deletions src/chunk.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ typedef enum {
OP_LESS,
OP_ADD,
OP_SUBTRACT,
OP_BITWISE_NOT,
OP_BITWISE_OR,
OP_BITWISE_XOR,
OP_BITWISE_AND,
OP_BITWISE_LEFT_SHIFT,
OP_BITWISE_RIGHT_SHIFT,
OP_INCREMENT,
OP_DECREMENT,
OP_MULTIPLY,
Expand Down
44 changes: 23 additions & 21 deletions src/cmake-build-release/CMakeFiles/qi.dir/C.includecache
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,40 @@ stdint.h
wchar.h
-

/Users/andrewyang/CLionProjects/qi/src/memory.h
common.h
/Users/andrewyang/CLionProjects/qi/src/common.h
object.h
/Users/andrewyang/CLionProjects/qi/src/object.h

/Users/andrewyang/CLionProjects/qi/src/object.c
/Users/andrewyang/CLionProjects/qi/src/compiler.c
stdio.h
-
stdlib.h
-
string.h
-
common.h
/Users/andrewyang/CLionProjects/qi/src/common.h
compiler.h
/Users/andrewyang/CLionProjects/qi/src/compiler.h
memory.h
/Users/andrewyang/CLionProjects/qi/src/memory.h
scanner.h
/Users/andrewyang/CLionProjects/qi/src/scanner.h
debug.h
/Users/andrewyang/CLionProjects/qi/src/debug.h

/Users/andrewyang/CLionProjects/qi/src/compiler.h
object.h
/Users/andrewyang/CLionProjects/qi/src/object.h
table.h
/Users/andrewyang/CLionProjects/qi/src/table.h
value.h
/Users/andrewyang/CLionProjects/qi/src/value.h
vm.h
/Users/andrewyang/CLionProjects/qi/src/vm.h

/Users/andrewyang/CLionProjects/qi/src/debug.h
chunk.h
/Users/andrewyang/CLionProjects/qi/src/chunk.h

/Users/andrewyang/CLionProjects/qi/src/memory.h
common.h
/Users/andrewyang/CLionProjects/qi/src/common.h
object.h
/Users/andrewyang/CLionProjects/qi/src/object.h

/Users/andrewyang/CLionProjects/qi/src/object.h
common.h
/Users/andrewyang/CLionProjects/qi/src/common.h
Expand All @@ -54,16 +66,6 @@ table.h
value.h
/Users/andrewyang/CLionProjects/qi/src/value.h

/Users/andrewyang/CLionProjects/qi/src/scanner.c
stdio.h
-
string.h
-
common.h
/Users/andrewyang/CLionProjects/qi/src/common.h
scanner.h
/Users/andrewyang/CLionProjects/qi/src/scanner.h

/Users/andrewyang/CLionProjects/qi/src/scanner.h

/Users/andrewyang/CLionProjects/qi/src/table.h
Expand Down
Binary file modified src/cmake-build-release/CMakeFiles/qi.dir/compiler.c.o
Binary file not shown.
Binary file modified src/cmake-build-release/CMakeFiles/qi.dir/debug.c.o
Binary file not shown.
Binary file modified src/cmake-build-release/CMakeFiles/qi.dir/object.c.o
Binary file not shown.
Binary file modified src/cmake-build-release/CMakeFiles/qi.dir/scanner.c.o
Binary file not shown.
Binary file modified src/cmake-build-release/CMakeFiles/qi.dir/vm.c.o
Binary file not shown.
4 changes: 2 additions & 2 deletions src/cmake-build-release/Testing/Temporary/LastTest.log
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Start testing: Dec 30 23:42 MST
Start testing: Jan 02 22:58 MST
----------------------------------------------------------
End testing: Dec 30 23:42 MST
End testing: Jan 02 22:58 MST
Binary file modified src/cmake-build-release/qi
Binary file not shown.
82 changes: 53 additions & 29 deletions src/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ typedef enum {
PREC_ASSIGNMENT, // =
PREC_OR, // 或
PREC_AND, // 和
PREC_EQUALITY, // 等 不 等
PREC_EQUALITY, // 等 不 等 位不
PREC_COMPARISON, // 大 小 大等 小等
PREC_BIT_OR, // 位或
PREC_BIT_XOR, // 位异或
PREC_BIT_AND, // 位和
PREC_BIT_SHIFT, // 位左移 位右移
PREC_TERM, // + -
PREC_FACTOR, // * /
PREC_UNARY, // ! -
Expand Down Expand Up @@ -415,17 +419,22 @@ static void binary(bool canAssign) {
parsePrecedence((Precedence)(rule->precedence + 1));

switch (operatorType) {
case TOKEN_BANG_EQUAL: emitBytes(OP_EQUAL, OP_NOT); break;
case TOKEN_EQUAL_EQUAL: emitByte(OP_EQUAL); break;
case TOKEN_GREATER: emitByte(OP_GREATER); break;
case TOKEN_GREATER_EQUAL: emitBytes(OP_LESS, OP_NOT); break;
case TOKEN_LESS: emitByte(OP_LESS); break;
case TOKEN_LESS_EQUAL: emitBytes(OP_GREATER, OP_NOT); break;
case TOKEN_PLUS: emitByte(OP_ADD); break;
case TOKEN_MINUS: emitByte(OP_SUBTRACT); break;
case TOKEN_STAR: emitByte(OP_MULTIPLY); break;
case TOKEN_SLASH: emitByte(OP_DIVIDE); break;
case TOKEN_PERCENT: emitByte(OP_MODULO); break;
case TOKEN_BANG_EQUAL: emitBytes(OP_EQUAL, OP_NOT); break;
case TOKEN_EQUAL_EQUAL: emitByte(OP_EQUAL); break;
case TOKEN_GREATER: emitByte(OP_GREATER); break;
case TOKEN_GREATER_EQUAL: emitBytes(OP_LESS, OP_NOT); break;
case TOKEN_LESS: emitByte(OP_LESS); break;
case TOKEN_LESS_EQUAL: emitBytes(OP_GREATER, OP_NOT); break;
case TOKEN_PLUS: emitByte(OP_ADD); break;
case TOKEN_MINUS: emitByte(OP_SUBTRACT); break;
case TOKEN_STAR: emitByte(OP_MULTIPLY); break;
case TOKEN_SLASH: emitByte(OP_DIVIDE); break;
case TOKEN_PERCENT: emitByte(OP_MODULO); break;
case TOKEN_BITWISE_OR: emitByte(OP_BITWISE_OR); break;
case TOKEN_BITWISE_XOR: emitByte(OP_BITWISE_XOR); break;
case TOKEN_BITWISE_AND: emitByte(OP_BITWISE_AND); break;
case TOKEN_BITWISE_LEFT_SHIFT: emitByte(OP_BITWISE_LEFT_SHIFT); break;
case TOKEN_BITWISE_RIGHT_SHIFT: emitByte(OP_BITWISE_RIGHT_SHIFT); break;
default: return; // Unreachable.
}
}
Expand Down Expand Up @@ -657,6 +666,7 @@ static void unary(bool canAssign) {
switch (operatorType) {
case TOKEN_BANG: emitByte(OP_NOT); break;
case TOKEN_MINUS: emitByte(OP_NEGATE); break;
case TOKEN_BITWISE_NOT: emitByte(OP_BITWISE_NOT); break;
case TOKEN_PLUS_PLUS:
case TOKEN_MINUS_MINUS: {
uint8_t op1 = -1, op2 = -1;
Expand Down Expand Up @@ -700,13 +710,14 @@ ParseRule rules[] = {
[TOKEN_MINUS] = {unary, binary, PREC_TERM},
[TOKEN_PLUS] = {NULL, binary, PREC_TERM},
[TOKEN_MINUS_MINUS] = {unary, postfix, PREC_CALL},
[TOKEN_PLUS_PLUS] = {unary, postfix, PREC_CALL},
[TOKEN_PLUS_PLUS] = {unary, postfix, PREC_CALL},
[TOKEN_SEMICOLON] = {NULL, NULL, PREC_NONE},
[TOKEN_SLASH] = {NULL, binary, PREC_FACTOR},
[TOKEN_STAR] = {NULL, binary, PREC_FACTOR},
[TOKEN_PERCENT] = {NULL, binary, PREC_FACTOR},
[TOKEN_BANG] = {unary, NULL, PREC_NONE},
[TOKEN_BANG_EQUAL] = {NULL, binary, PREC_EQUALITY},
[TOKEN_PERCENT] = {NULL, binary, PREC_FACTOR},
[TOKEN_BANG] = {unary, NULL, PREC_NONE},
[TOKEN_BANG_EQUAL] = {NULL, binary, PREC_EQUALITY},
[TOKEN_BITWISE_NOT] = {unary, NULL, PREC_NONE},
[TOKEN_EQUAL] = {NULL, NULL, PREC_NONE},
[TOKEN_PLUS_EQUAL] = {NULL, NULL, PREC_NONE},
[TOKEN_MINUS_EQUAL] = {NULL, NULL, PREC_NONE},
Expand All @@ -715,24 +726,29 @@ ParseRule rules[] = {
[TOKEN_GREATER_EQUAL] = {NULL, binary, PREC_COMPARISON},
[TOKEN_LESS] = {NULL, binary, PREC_COMPARISON},
[TOKEN_LESS_EQUAL] = {NULL, binary, PREC_COMPARISON},
[TOKEN_IDENTIFIER] = {variable, NULL, PREC_NONE},
[TOKEN_STRING] = {string, NULL, PREC_NONE},
[TOKEN_BITWISE_LEFT_SHIFT] = {NULL, binary, PREC_BIT_SHIFT},
[TOKEN_BITWISE_RIGHT_SHIFT] = {NULL, binary, PREC_BIT_SHIFT},
[TOKEN_IDENTIFIER] = {variable, NULL, PREC_NONE},
[TOKEN_STRING] = {string, NULL, PREC_NONE},
[TOKEN_LEFT_BRACKET] = {list, subscript, PREC_SUBSCRIPT},
[TOKEN_RIGHT_BRACKET] = {NULL, NULL, PREC_NONE},
[TOKEN_NUMBER] = {number, NULL, PREC_NONE},
[TOKEN_AND] = {NULL, and_, PREC_AND},
[TOKEN_BITWISE_AND] = {NULL, binary, PREC_BIT_AND},
[TOKEN_CLASS] = {NULL, NULL, PREC_NONE},
[TOKEN_ELSE] = {NULL, NULL, PREC_NONE},
[TOKEN_FALSE] = {literal, NULL, PREC_NONE},
[TOKEN_FALSE] = {literal, NULL, PREC_NONE},
[TOKEN_FOR] = {NULL, NULL, PREC_NONE},
[TOKEN_FUN] = {NULL, NULL, PREC_NONE},
[TOKEN_IF] = {NULL, NULL, PREC_NONE},
[TOKEN_NIL] = {literal, NULL, PREC_NONE},
[TOKEN_NIL] = {literal, NULL, PREC_NONE},
[TOKEN_OR] = {NULL, or_, PREC_OR},
[TOKEN_BITWISE_OR] = {NULL, binary, PREC_BIT_OR},
[TOKEN_BITWISE_XOR] = {NULL, binary, PREC_BIT_XOR},
[TOKEN_RETURN] = {NULL, NULL, PREC_NONE},
[TOKEN_SUPER] = {super_, NULL, PREC_NONE},
[TOKEN_THIS] = {this_, NULL, PREC_NONE},
[TOKEN_TRUE] = {literal, NULL, PREC_NONE},
[TOKEN_SUPER] = {super_, NULL, PREC_NONE},
[TOKEN_THIS] = {this_, NULL, PREC_NONE},
[TOKEN_TRUE] = {literal, NULL, PREC_NONE},
[TOKEN_VAR] = {NULL, NULL, PREC_NONE},
[TOKEN_WHILE] = {NULL, NULL, PREC_NONE},
[TOKEN_ERROR] = {NULL, NULL, PREC_NONE},
Expand All @@ -751,6 +767,7 @@ static void parsePrecedence(Precedence precedence) {
prefixRule(canAssign);

while (precedence <= getRule(parser.current.type)->precedence) {
if (parser.current.line > parser.previous.line) break;
advance();
ParseFn infixRule = getRule(parser.previous.type)->infix;
infixRule(canAssign);
Expand Down Expand Up @@ -937,15 +954,17 @@ static void varDeclaration() {
} else {
emitByte(OP_NIL);
}
consume(TOKEN_SEMICOLON, L"在变量声明之后期待「 ;」。");
// consume(TOKEN_SEMICOLON, L"在变量声明之后期待「 ;」。");
match(TOKEN_SEMICOLON);

defineVariable(global);
}

static void expressionStatement() {
expression();
consume(TOKEN_SEMICOLON, L"表达式后期待「 ;」。");
// consume(TOKEN_SEMICOLON, L"表达式后期待「 ;」。");
emitByte(OP_POP);
match(TOKEN_SEMICOLON);
}

static void forStatement() {
Expand Down Expand Up @@ -1038,15 +1057,17 @@ static void returnStatement() {
error(L"无法从顶级代码返回。");
}

if (match(TOKEN_SEMICOLON)) {
if (match(TOKEN_SEMICOLON) || check(TOKEN_RIGHT_BRACE)) {
emitReturn();
} else {
if (current->type == TYPE_INITIALIZER) {
error(L"不能从初始值设定项返回值。");
}

expression();
consume(TOKEN_SEMICOLON, L"返回值后期得「 ;」。");
// consume(TOKEN_SEMICOLON, L"返回值后期得「 ;」。");
match(TOKEN_SEMICOLON);

emitByte(OP_RETURN);
}
}
Expand Down Expand Up @@ -1176,7 +1197,8 @@ static void continueStatement() {
error(L"不能在循环外使用「继续」。");
}

consume(TOKEN_SEMICOLON, L"在「继续」之后期待「 ;」。");
// consume(TOKEN_SEMICOLON, L"在「继续」之后期待「 ;」。");
match(TOKEN_SEMICOLON);

// Discard any locals created inside the loop.
for (int i = current->localCount - 1; i >= 0 && current->locals[i].depth > innermostLoopScopeDepth; i--) {
Expand All @@ -1192,7 +1214,8 @@ static void breakStatement() {
error(L"不能在循环外或切换使用「打断」。");
}

consume(TOKEN_SEMICOLON, L"在「打断」之后期待「 ;」。");
// consume(TOKEN_SEMICOLON, L"在「打断」之后期待「 ;」。");
match(TOKEN_SEMICOLON);

if (innermostLoopStart > innermostSwitchStart) {
// Discard any locals created inside the loop.
Expand All @@ -1214,6 +1237,7 @@ static void synchronize() {

while (parser.current.type != TOKEN_EOF) {
if (parser.previous.type == TOKEN_SEMICOLON) return;
else if (parser.previous.line != parser.current.line) return;
switch (parser.current.type) {
case TOKEN_CLASS:
case TOKEN_FUN:
Expand Down
15 changes: 13 additions & 2 deletions src/scanner.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,7 @@ static TokenType identifierType() {
case L'大':
if (scanner.current - scanner.start > 1) {
switch (scanner.start[1]) {
case L'等':
return checkKeyword(2, 0, L"", TOKEN_GREATER_EQUAL);
case L'等': return checkKeyword(2, 0, L"", TOKEN_GREATER_EQUAL);
}
}
return checkKeyword(1, 0, L"", TOKEN_GREATER);
Expand All @@ -156,6 +155,18 @@ static TokenType identifierType() {
}
}
return checkKeyword(1, 0, L"", TOKEN_LESS);
case L'位':
if (scanner.current - scanner.start > 1) {
switch (scanner.start[1]) {
case L'不': return checkKeyword(2, 0, L"", TOKEN_BITWISE_NOT);
case L'和': return checkKeyword(2, 0, L"", TOKEN_BITWISE_AND);
case L'或': return checkKeyword(2, 0, L"", TOKEN_BITWISE_OR);
case L'异': return checkKeyword(2, 1, L"或", TOKEN_BITWISE_XOR);
case L'左': return checkKeyword(2, 1, L"移", TOKEN_BITWISE_LEFT_SHIFT);
case L'右': return checkKeyword(2, 1, L"移", TOKEN_BITWISE_RIGHT_SHIFT);
}
}
break;
}

return TOKEN_IDENTIFIER;
Expand Down
5 changes: 4 additions & 1 deletion src/scanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@ typedef enum {
TOKEN_RETURN, TOKEN_SUPER, TOKEN_THIS, TOKEN_TRUE,
TOKEN_VAR, TOKEN_WHILE, TOKEN_CASE, TOKEN_DEFAULT,
TOKEN_SWITCH, TOKEN_CONTINUE, TOKEN_BREAK,
TOKEN_BITWISE_AND, TOKEN_BITWISE_OR, TOKEN_BITWISE_XOR,
TOKEN_BITWISE_NOT, TOKEN_BITWISE_LEFT_SHIFT,
TOKEN_BITWISE_RIGHT_SHIFT,

TOKEN_ERROR, TOKEN_EOF,
TOKEN_NEWLINE, TOKEN_ERROR, TOKEN_EOF,
} TokenType;

typedef struct {
Expand Down
34 changes: 34 additions & 0 deletions src/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,17 @@ static InterpretResult run() {
double a = AS_NUMBER(pop()); \
push(valueType(a op b)); \
} while (false)
#define BINARY_BITWISE_OP(valueType, op) \
do { \
if (!IS_NUMBER(peek(0)) || !IS_NUMBER(peek(1))) { \
frame->ip = ip; \
runtimeError(L"操作数必须是数字。"); \
return INTERPRET_RUNTIME_ERROR; \
} \
int32_t b = (int32_t)AS_NUMBER(pop()); \
int32_t a = (int32_t)AS_NUMBER(pop()); \
push(valueType(a op b)); \
} while (false)
#define BINARY_FUNC_OP(valueType, op) \
do { \
if (!IS_NUMBER(peek(0)) || !IS_NUMBER(peek(1))) { \
Expand Down Expand Up @@ -664,6 +675,21 @@ static InterpretResult run() {
case OP_MODULO:
BINARY_FUNC_OP(NUMBER_VAL, fmod);
break;
case OP_BITWISE_AND:
BINARY_BITWISE_OP(NUMBER_VAL, &);
break;
case OP_BITWISE_OR:
BINARY_BITWISE_OP(NUMBER_VAL, |);
break;
case OP_BITWISE_XOR:
BINARY_BITWISE_OP(NUMBER_VAL, ^);
break;
case OP_BITWISE_LEFT_SHIFT:
BINARY_BITWISE_OP(NUMBER_VAL, <<);
break;
case OP_BITWISE_RIGHT_SHIFT:
BINARY_BITWISE_OP(NUMBER_VAL, >>);
break;
case OP_NOT:
push(BOOL_VAL(isFalsey(pop())));
break;
Expand All @@ -675,6 +701,14 @@ static InterpretResult run() {
}
push(NUMBER_VAL(-AS_NUMBER(pop())));
break;
case OP_BITWISE_NOT:
if (!IS_NUMBER(peek(0))) {
frame->ip = ip;
runtimeError(L"操作数必须是数字。");
return INTERPRET_RUNTIME_ERROR;
}
push(NUMBER_VAL(~(int32_t)AS_NUMBER(pop())));
break;
case OP_INCREMENT: {
if (!IS_NUMBER(peek(0))) {
frame->ip = ip;
Expand Down
4 changes: 2 additions & 2 deletions test/array/define.qi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
变量 富 =【"a","b","c"】
变量 富 =【"a","b","c"】
打印行(富); // 期待:【a,b,c】
变量 吧 =【】
变量 吧 =【】
打印行(吧); // 期待:【】
打印行(【1,2,3】); // 期待:【1,2,3】
2 changes: 1 addition & 1 deletion test/array/indexing.qi
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
变量 富 =【2 - 1,"b",假】
变量 富 =【2 - 1,"b",假】

打印行(富【2 - 2】); // 期待:1

Expand Down
Loading

0 comments on commit a580f38

Please sign in to comment.