visitFuncDecl method
Implementation
@override
Uint8List visitFuncDecl(FuncDecl stmt) {
// final savedCurFunc = _curFunc;
final bytesBuilder = BytesBuilder();
// TODO: generic param
if (stmt.category != FunctionCategory.literal) {
bytesBuilder.addByte(HTOpCode.funcDecl);
// funcBytesBuilder.addByte(HTOpCode.funcDecl);
bytesBuilder.add(_parseIdentifier(stmt.internalName));
if (stmt.id != null) {
bytesBuilder.addByte(1); // bool: hasId
bytesBuilder.add(_parseIdentifier(stmt.id!.id));
} else {
bytesBuilder.addByte(0); // bool: hasId
}
if (stmt.classId != null) {
bytesBuilder.addByte(1); // bool: hasClassId
bytesBuilder.add(_parseIdentifier(stmt.classId!));
} else {
bytesBuilder.addByte(0); // bool: hasClassId
}
if (stmt.externalTypeId != null) {
bytesBuilder.addByte(1); // bool: hasExternalTypedef
bytesBuilder.add(_parseIdentifier(stmt.externalTypeId!));
} else {
bytesBuilder.addByte(0); // bool: hasExternalTypedef
}
bytesBuilder.addByte(stmt.category.index);
bytesBuilder.addByte(stmt.isAsync ? 1 : 0);
bytesBuilder.addByte(stmt.isField ? 1 : 0);
bytesBuilder.addByte(stmt.isExternal ? 1 : 0);
bytesBuilder.addByte(stmt.isStatic ? 1 : 0);
bytesBuilder.addByte(stmt.isTopLevel ? 1 : 0);
bytesBuilder.addByte(stmt.isConstValue ? 1 : 0);
} else {
bytesBuilder.addByte(HTOpCode.local);
bytesBuilder.addByte(HTValueTypeCode.function);
bytesBuilder.add(_parseIdentifier(stmt.internalName));
if (stmt.externalTypeId != null) {
bytesBuilder.addByte(1);
bytesBuilder.add(_parseIdentifier(stmt.externalTypeId!));
} else {
bytesBuilder.addByte(0);
}
bytesBuilder.addByte(stmt.isAsync ? 1 : 0);
}
bytesBuilder.addByte(stmt.hasParamDecls ? 1 : 0);
bytesBuilder.addByte(stmt.isVariadic ? 1 : 0);
bytesBuilder.addByte(stmt.minArity);
bytesBuilder.addByte(stmt.maxArity);
bytesBuilder.addByte(stmt.paramDecls.length); // max 255
for (var param in stmt.paramDecls) {
final bytes = visitParamDecl(param);
bytesBuilder.add(bytes);
}
if (stmt.returnType != null) {
bytesBuilder.addByte(1); // bool: hasReturnType
// use compileAst here because there are multiple types of typeExpr
final bytes = compileAST(stmt.returnType!);
bytesBuilder.add(bytes);
} else {
bytesBuilder.addByte(0); // bool: hasReturnType
}
if (stmt.category == FunctionCategory.constructor) {
// referring to another constructor
if (stmt.redirectingCtorCallExpr != null) {
bytesBuilder.addByte(1); // bool: hasRefCtor
final bytes =
visitReferConstructCallExpr(stmt.redirectingCtorCallExpr!);
bytesBuilder.add(bytes);
} else {
bytesBuilder.addByte(0); // bool: hasRefCtor
}
}
// definition body
if (stmt.definition != null) {
bytesBuilder.addByte(1); // bool: has definition
bytesBuilder.add(_uint16(stmt.definition!.line));
bytesBuilder.add(_uint16(stmt.definition!.column));
final body = compileAST(stmt.definition!);
bytesBuilder.add(_uint16(body.length + 1)); // definition bytes length
bytesBuilder.add(body);
bytesBuilder.addByte(HTOpCode.endOfFunc);
} else {
bytesBuilder.addByte(0); // bool: has no definition
}
// if (stmt.category != FunctionCategory.literal && !stmt.isField) {
// bytesBuilder.addByte(HTOpCode.endOfStmt);
// }
return bytesBuilder.toBytes();
}