Skip to content

Commit

Permalink
refactor(vm): class op
Browse files Browse the repository at this point in the history
  • Loading branch information
zyrouge committed Dec 10, 2024
1 parent d7fd64b commit fef86bf
Show file tree
Hide file tree
Showing 24 changed files with 181 additions and 87 deletions.
14 changes: 6 additions & 8 deletions packages/beize_compiler/example/project/dev.beize
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
printHello := -> async {
print("Hello World");
test := $ {
hi: "hi",
static hi: "hi static",
};

main := -> async {
printHello().await;
};

main().await;
print(Function is null);
print(test.hi);
print(test().hi);
print(test() is test);
17 changes: 17 additions & 0 deletions packages/beize_compiler/lib/compiler/compiler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'state.dart';

enum BeizeCompilerMode {
function,
clazz,
script,
}

Expand Down Expand Up @@ -87,6 +88,22 @@ class BeizeCompiler {
return derived;
}

BeizeCompiler createClassCompiler() {
final BeizeCompiler derived = BeizeCompiler._(
scanner,
mode: BeizeCompilerMode.clazz,
root: root,
modulePath: modulePath,
moduleIndex: moduleIndex,
modules: modules,
constants: constants,
parent: this,
options: options,
);
derived.prepare(isAsync: false);
return derived;
}

Future<BeizeCompiler> createModuleCompiler(
final int moduleIndex,
final String path, {
Expand Down
60 changes: 52 additions & 8 deletions packages/beize_compiler/lib/compiler/parser/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,46 @@ abstract class BeizeParser {
compiler.copyTokenState(functionCompiler);
}

static void parseClass(final BeizeCompiler compiler) {
final bool hasParentClass = !compiler.check(BeizeTokens.braceLeft);
if (hasParentClass) {
parseExpression(compiler);
}
final BeizeCompiler classCompiler = compiler.createClassCompiler();
classCompiler.emitOpCode(BeizeOpCodes.opBeginScope);
compiler.emitConstant(classCompiler.currentFunction);
int staticCount = 0;
int objectCount = 0;
bool cont = true;
compiler.consume(BeizeTokens.braceLeft);
while (cont && !compiler.check(BeizeTokens.braceRight)) {
final bool isStatic = compiler.match(BeizeTokens.staticKw);
if (isStatic) {
parseObjectKey(compiler);
compiler.consume(BeizeTokens.colon);
parseExpression(compiler);
staticCount++;
} else {
classCompiler.copyTokenState(compiler);
parseObjectKey(classCompiler);
classCompiler.consume(BeizeTokens.colon);
parseExpression(classCompiler);
compiler.copyTokenState(classCompiler);
objectCount++;
}
cont = compiler.match(BeizeTokens.comma);
}
classCompiler.copyTokenState(compiler);
classCompiler.emitOpCode(BeizeOpCodes.opObject);
classCompiler.emitCode(objectCount);
classCompiler.emitOpCode(BeizeOpCodes.opReturn);
classCompiler.emitOpCode(BeizeOpCodes.opEndScope);
compiler.consume(BeizeTokens.braceRight);
compiler.emitOpCode(BeizeOpCodes.opClass);
compiler.emitCode(hasParentClass ? 1 : 0);
compiler.emitCode(staticCount);
}

static void parseCall(final BeizeCompiler compiler) {
int count = 0;
bool cont = true;
Expand All @@ -651,18 +691,22 @@ abstract class BeizeParser {
compiler.emitCode(count);
}

static void parseObjectKey(final BeizeCompiler compiler) {
if (compiler.match(BeizeTokens.bracketLeft)) {
parseExpression(compiler);
compiler.consume(BeizeTokens.bracketRight);
return;
}
compiler.consume(BeizeTokens.identifier);
final String key = compiler.previousToken.literal as String;
compiler.emitConstant(key);
}

static void parseObject(final BeizeCompiler compiler) {
int count = 0;
bool cont = true;
while (cont && !compiler.check(BeizeTokens.braceRight)) {
if (compiler.match(BeizeTokens.bracketLeft)) {
parseExpression(compiler);
compiler.consume(BeizeTokens.bracketRight);
} else {
compiler.consume(BeizeTokens.identifier);
final String key = compiler.previousToken.literal as String;
compiler.emitConstant(key);
}
parseObjectKey(compiler);
compiler.consume(BeizeTokens.colon);
parseExpression(compiler);
count++;
Expand Down
1 change: 1 addition & 0 deletions packages/beize_compiler/lib/compiler/parser/rules.dart
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ class BeizeParseRule {
precedence: BeizePrecedence.caret,
infix: BeizeParser.parseBinaryExpression,
),
BeizeTokens.dollar: BeizeParseRule(prefix: BeizeParser.parseClass),
BeizeTokens.identifier: BeizeParseRule(prefix: BeizeParser.parseIdentifier),
BeizeTokens.number: BeizeParseRule(prefix: BeizeParser.parseNumber),
BeizeTokens.string: BeizeParseRule(prefix: BeizeParser.parseString),
Expand Down
11 changes: 11 additions & 0 deletions packages/beize_compiler/lib/disassembler/disassembler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,17 @@ class BeizeDisassembler {
);
return 1;

case BeizeOpCodes.opClass:
final bool hasParentClass = chunk.codeAt(ip + 1) == 1;
final int popCount = chunk.codeAt(ip + 2);
writeInstruction(
opCode,
ip,
chunk.lineAt(ip),
'{so}(parent = $hasParentClass, popCount = $popCount)',
);
return 2;

default:
writeInstruction(opCode, ip, chunk.lineAt(ip));
return 0;
Expand Down
2 changes: 1 addition & 1 deletion packages/beize_compiler/lib/lexer/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class BeizeLexerUtils {
static bool isQuote(final String char) =>
char == "'" || char == '"' || char == '`';
static bool isAlpha(final String char) =>
r'$_abcdefghijklmnopqrstuvwxyz'.contains(char.toLowerCase());
'_abcdefghijklmnopqrstuvwxyz'.contains(char.toLowerCase());
static bool isAlphaNumeric(final String char) =>
isAlpha(char) || isNumeric(char);
}
5 changes: 4 additions & 1 deletion packages/beize_compiler/lib/scanner/rules/identifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ abstract class BeizeIdentifierScanner {
BeizeTokens.awaitKw,
BeizeTokens.onlyKw,
BeizeTokens.isKw,
BeizeTokens.staticKw,
};

static final Map<String, BeizeTokens> keywordsMap = keywords.asNameMap().map(
Expand All @@ -52,7 +53,9 @@ abstract class BeizeIdentifierScanner {
BeizeInputIteration current = start;
while (!scanner.input.isEndOfLine()) {
current = scanner.input.peek();
if (!BeizeLexerUtils.isAlphaNumeric(current.char)) break;
if (!BeizeLexerUtils.isAlphaNumeric(current.char)) {
break;
}
buffer.write(current.char);
scanner.input.advance();
}
Expand Down
1 change: 1 addition & 0 deletions packages/beize_compiler/lib/scanner/rules/rules.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class BeizeScannerRules {
constructOffset1ScanFn(BeizeTokens.bang),
constructOffset1ScanFn(BeizeTokens.lesserThan),
constructOffset1ScanFn(BeizeTokens.greaterThan),
constructOffset1ScanFn(BeizeTokens.dollar),
],
);

Expand Down
4 changes: 4 additions & 0 deletions packages/beize_compiler/lib/token/tokens.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ enum BeizeTokens {
logicalOrEqual, // ||=
caretEqual, // ^=
nullOrEqual, // ??=
dollar, // $

trueKw, // true
falseKw, // false
Expand All @@ -81,6 +82,7 @@ enum BeizeTokens {
awaitKw, // await
onlyKw, // only
isKw, // is
staticKw, // static
}

const Map<BeizeTokens, String> _tokensCodeMap = <BeizeTokens, String>{
Expand Down Expand Up @@ -141,6 +143,7 @@ const Map<BeizeTokens, String> _tokensCodeMap = <BeizeTokens, String>{
BeizeTokens.logicalOrEqual: '||=',
BeizeTokens.caretEqual: '^=',
BeizeTokens.nullOrEqual: '??=',
BeizeTokens.dollar: r'$',
BeizeTokens.trueKw: 'true',
BeizeTokens.falseKw: 'false',
BeizeTokens.ifKw: 'if',
Expand All @@ -163,6 +166,7 @@ const Map<BeizeTokens, String> _tokensCodeMap = <BeizeTokens, String>{
BeizeTokens.awaitKw: 'await',
BeizeTokens.onlyKw: 'only',
BeizeTokens.isKw: 'is',
BeizeTokens.staticKw: 'static',
};

extension OutreTokensUtils on BeizeTokens {
Expand Down
23 changes: 0 additions & 23 deletions packages/beize_shared/lib/bytecode/constants/class.dart

This file was deleted.

1 change: 0 additions & 1 deletion packages/beize_shared/lib/bytecode/constants/exports.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export 'class.dart';
export 'constant.dart';
export 'function.dart';
export 'program.dart';
1 change: 1 addition & 0 deletions packages/beize_shared/lib/bytecode/op_codes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ enum BeizeOpCodes {
opSetProperty,
opList,
opObject,
opClass,
opThrow,
opBeginTry,
opEndTry,
Expand Down
9 changes: 0 additions & 9 deletions packages/beize_vm/lib/values/class/class.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
import '../../vm/exports.dart';
import '../exports.dart';

abstract class BeizeClassValue extends BeizeNativeObjectValue
implements BeizeCallableValue {
bool kInstance(final BeizeObjectValue value);

BeizeObjectValue kInstantiate(final BeizeCallableCall call);

@override
BeizeInterpreterResult kCall(final BeizeCallableCall call) {
final BeizeObjectValue value = kInstantiate(call);
return BeizeInterpreterResult.success(value);
}

@override
BeizeClassValue get kClass => this;
}
9 changes: 9 additions & 0 deletions packages/beize_vm/lib/values/class/native_class.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import '../../vm/exports.dart';
import '../exports.dart';

abstract class BeizeNativeClassValue extends BeizeClassValue {
@override
final BeizeValueKind kind = BeizeValueKind.nativeClazz;

BeizeObjectValue kInstantiate(final BeizeCallableCall call);

@override
BeizeInterpreterResult kCall(final BeizeCallableCall call) {
final BeizeObjectValue value = kInstantiate(call);
return BeizeInterpreterResult.success(value);
}

@override
String kToString() => '<native class>';

Expand Down
19 changes: 10 additions & 9 deletions packages/beize_vm/lib/values/class/vm_class.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import '../../bytecode.dart';
import '../../vm/exports.dart';
import '../exports.dart';

class BeizeVMClassValue extends BeizeClassValue {
BeizeVMClassValue(this.constant);

final BeizeClassConstant constant;
late final BeizeClassValue? parentClass;
late final BeizeCallableValue constructor;

@override
final BeizeValueKind kind = BeizeValueKind.clazz;
Expand All @@ -13,12 +12,14 @@ class BeizeVMClassValue extends BeizeClassValue {
bool kInstance(final BeizeObjectValue value) => value is BeizeClassValue;

@override
BeizeObjectValue kInstantiate(final BeizeCallableCall call) {
throw UnimplementedError();
}
BeizeInterpreterResult kCall(final BeizeCallableCall call) =>
constructor.kCall(call);

@override
BeizeVMClassValue kClone() => BeizeVMClassValue(constant)..kCopyFrom(this);
BeizeVMClassValue kClone() => BeizeVMClassValue()
..parentClass = parentClass
..constructor = constructor
..kCopyFrom(this);

@override
String kToString() => '<class>';
Expand All @@ -27,5 +28,5 @@ class BeizeVMClassValue extends BeizeClassValue {
bool get isTruthy => true;

@override
int get kHashCode => constant.hashCode;
int get kHashCode => Object.hash(parentClass, constructor);
}
5 changes: 3 additions & 2 deletions packages/beize_vm/lib/values/function/function.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ class BeizeFunctionValue extends BeizeNativeObjectValue
@override
BeizeInterpreterResult kCall(final BeizeCallableCall call) {
if (!constant.isAsync) {
final BeizeInterpreterResult result = BeizeInterpreter(call.frame).run();
return result;
final BeizeCallFrame frame =
call.frame.prepareCallFunctionValue(call.arguments, this);
return BeizeInterpreter(frame).run();
}
final BeizeUnawaitedValue value = BeizeUnawaitedValue(
call.arguments,
Expand Down
2 changes: 1 addition & 1 deletion packages/beize_vm/lib/values/object/object_class.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class BeizeObjectClassValue extends BeizeNativeClassValue {
BeizeNativeFunctionValue.sync(
(final BeizeCallableCall call) {
final BeizeListValue value = call.argumentAt(0);
final BeizeMapValue nValue = BeizeMapValue();
final BeizeObjectValue nValue = BeizeVMObjectValue();
for (final MapEntry<BeizeValue, BeizeValue> x in value.entries()) {
nValue.set(x.key, x.value);
}
Expand Down
Loading

0 comments on commit fef86bf

Please sign in to comment.