void wrenLoadMetaLibrary(WrenVM* vm) { wrenInterpret(vm, "", metaModuleSource); ObjModule* coreModule = wrenGetCoreModule(vm); // The methods on "Meta" are static, so get the metaclass for the Meta class. ObjClass* meta = AS_CLASS(wrenFindVariable(vm, coreModule, "Meta")); PRIMITIVE(meta->obj.classObj, "eval(_)", meta_eval); }
void wrenInitializeCore(WrenVM* vm) { ObjModule* coreModule = wrenNewModule(vm, NULL); wrenPushRoot(vm, (Obj*)coreModule); // The core module's key is null in the module map. wrenMapSet(vm, vm->modules, NULL_VAL, OBJ_VAL(coreModule)); wrenPopRoot(vm); // coreModule. // Define the root Object class. This has to be done a little specially // because it has no superclass. vm->objectClass = defineClass(vm, coreModule, "Object"); PRIMITIVE(vm->objectClass, "!", object_not); PRIMITIVE(vm->objectClass, "==(_)", object_eqeq); PRIMITIVE(vm->objectClass, "!=(_)", object_bangeq); PRIMITIVE(vm->objectClass, "is(_)", object_is); PRIMITIVE(vm->objectClass, "toString", object_toString); PRIMITIVE(vm->objectClass, "type", object_type); // Now we can define Class, which is a subclass of Object. vm->classClass = defineClass(vm, coreModule, "Class"); wrenBindSuperclass(vm, vm->classClass, vm->objectClass); PRIMITIVE(vm->classClass, "name", class_name); PRIMITIVE(vm->classClass, "supertype", class_supertype); PRIMITIVE(vm->classClass, "toString", class_toString); // Finally, we can define Object's metaclass which is a subclass of Class. ObjClass* objectMetaclass = defineClass(vm, coreModule, "Object metaclass"); // Wire up the metaclass relationships now that all three classes are built. vm->objectClass->obj.classObj = objectMetaclass; objectMetaclass->obj.classObj = vm->classClass; vm->classClass->obj.classObj = vm->classClass; // Do this after wiring up the metaclasses so objectMetaclass doesn't get // collected. wrenBindSuperclass(vm, objectMetaclass, vm->classClass); PRIMITIVE(objectMetaclass, "same(_,_)", object_same); // The core class diagram ends up looking like this, where single lines point // to a class's superclass, and double lines point to its metaclass: // // .------------------------------------. .====. // | .---------------. | # # // v | v | v # // .---------. .-------------------. .-------. # // | Object |==>| Object metaclass |==>| Class |==" // '---------' '-------------------' '-------' // ^ ^ ^ ^ ^ // | .--------------' # | # // | | # | # // .---------. .-------------------. # | # -. // | Base |==>| Base metaclass |======" | # | // '---------' '-------------------' | # | // ^ | # | // | .------------------' # | Example classes // | | # | // .---------. .-------------------. # | // | Derived |==>| Derived metaclass |==========" | // '---------' '-------------------' -' // The rest of the classes can now be defined normally. wrenInterpretInModule(vm, NULL, coreModuleSource); vm->boolClass = AS_CLASS(wrenFindVariable(vm, coreModule, "Bool")); PRIMITIVE(vm->boolClass, "toString", bool_toString); PRIMITIVE(vm->boolClass, "!", bool_not); vm->fiberClass = AS_CLASS(wrenFindVariable(vm, coreModule, "Fiber")); PRIMITIVE(vm->fiberClass->obj.classObj, "new(_)", fiber_new); PRIMITIVE(vm->fiberClass->obj.classObj, "abort(_)", fiber_abort); PRIMITIVE(vm->fiberClass->obj.classObj, "current", fiber_current); PRIMITIVE(vm->fiberClass->obj.classObj, "suspend()", fiber_suspend); PRIMITIVE(vm->fiberClass->obj.classObj, "yield()", fiber_yield); PRIMITIVE(vm->fiberClass->obj.classObj, "yield(_)", fiber_yield1); PRIMITIVE(vm->fiberClass, "call()", fiber_call); PRIMITIVE(vm->fiberClass, "call(_)", fiber_call1); PRIMITIVE(vm->fiberClass, "error", fiber_error); PRIMITIVE(vm->fiberClass, "isDone", fiber_isDone); PRIMITIVE(vm->fiberClass, "transfer()", fiber_transfer); PRIMITIVE(vm->fiberClass, "transfer(_)", fiber_transfer1); PRIMITIVE(vm->fiberClass, "transferError(_)", fiber_transferError); PRIMITIVE(vm->fiberClass, "try()", fiber_try); vm->fnClass = AS_CLASS(wrenFindVariable(vm, coreModule, "Fn")); PRIMITIVE(vm->fnClass->obj.classObj, "new(_)", fn_new); PRIMITIVE(vm->fnClass, "arity", fn_arity); fnCall(vm, "call()"); fnCall(vm, "call(_)"); fnCall(vm, "call(_,_)"); fnCall(vm, "call(_,_,_)"); fnCall(vm, "call(_,_,_,_)"); fnCall(vm, "call(_,_,_,_,_)"); fnCall(vm, "call(_,_,_,_,_,_)"); fnCall(vm, "call(_,_,_,_,_,_,_)"); fnCall(vm, "call(_,_,_,_,_,_,_,_)"); fnCall(vm, "call(_,_,_,_,_,_,_,_,_)"); fnCall(vm, "call(_,_,_,_,_,_,_,_,_,_)"); fnCall(vm, "call(_,_,_,_,_,_,_,_,_,_,_)"); fnCall(vm, "call(_,_,_,_,_,_,_,_,_,_,_,_)"); fnCall(vm, "call(_,_,_,_,_,_,_,_,_,_,_,_,_)"); fnCall(vm, "call(_,_,_,_,_,_,_,_,_,_,_,_,_,_)"); fnCall(vm, "call(_,_,_,_,_,_,_,_,_,_,_,_,_,_,_)"); fnCall(vm, "call(_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_)"); PRIMITIVE(vm->fnClass, "toString", fn_toString); vm->nullClass = AS_CLASS(wrenFindVariable(vm, coreModule, "Null")); PRIMITIVE(vm->nullClass, "!", null_not); PRIMITIVE(vm->nullClass, "toString", null_toString); vm->numClass = AS_CLASS(wrenFindVariable(vm, coreModule, "Num")); PRIMITIVE(vm->numClass->obj.classObj, "fromString(_)", num_fromString); PRIMITIVE(vm->numClass->obj.classObj, "pi", num_pi); PRIMITIVE(vm->numClass, "-(_)", num_minus); PRIMITIVE(vm->numClass, "+(_)", num_plus); PRIMITIVE(vm->numClass, "*(_)", num_multiply); PRIMITIVE(vm->numClass, "/(_)", num_divide); PRIMITIVE(vm->numClass, "<(_)", num_lt); PRIMITIVE(vm->numClass, ">(_)", num_gt); PRIMITIVE(vm->numClass, "<=(_)", num_lte); PRIMITIVE(vm->numClass, ">=(_)", num_gte); PRIMITIVE(vm->numClass, "&(_)", num_bitwiseAnd); PRIMITIVE(vm->numClass, "|(_)", num_bitwiseOr); PRIMITIVE(vm->numClass, "^(_)", num_bitwiseXor); PRIMITIVE(vm->numClass, "<<(_)", num_bitwiseLeftShift); PRIMITIVE(vm->numClass, ">>(_)", num_bitwiseRightShift); PRIMITIVE(vm->numClass, "abs", num_abs); PRIMITIVE(vm->numClass, "acos", num_acos); PRIMITIVE(vm->numClass, "asin", num_asin); PRIMITIVE(vm->numClass, "atan", num_atan); PRIMITIVE(vm->numClass, "ceil", num_ceil); PRIMITIVE(vm->numClass, "cos", num_cos); PRIMITIVE(vm->numClass, "floor", num_floor); PRIMITIVE(vm->numClass, "-", num_negate); PRIMITIVE(vm->numClass, "sin", num_sin); PRIMITIVE(vm->numClass, "sqrt", num_sqrt); PRIMITIVE(vm->numClass, "tan", num_tan); PRIMITIVE(vm->numClass, "%(_)", num_mod); PRIMITIVE(vm->numClass, "~", num_bitwiseNot); PRIMITIVE(vm->numClass, "..(_)", num_dotDot); PRIMITIVE(vm->numClass, "...(_)", num_dotDotDot); PRIMITIVE(vm->numClass, "atan(_)", num_atan2); PRIMITIVE(vm->numClass, "fraction", num_fraction); PRIMITIVE(vm->numClass, "isInfinity", num_isInfinity); PRIMITIVE(vm->numClass, "isInteger", num_isInteger); PRIMITIVE(vm->numClass, "isNan", num_isNan); PRIMITIVE(vm->numClass, "sign", num_sign); PRIMITIVE(vm->numClass, "toString", num_toString); PRIMITIVE(vm->numClass, "truncate", num_truncate); // These are defined just so that 0 and -0 are equal, which is specified by // IEEE 754 even though they have different bit representations. PRIMITIVE(vm->numClass, "==(_)", num_eqeq); PRIMITIVE(vm->numClass, "!=(_)", num_bangeq); vm->stringClass = AS_CLASS(wrenFindVariable(vm, coreModule, "String")); PRIMITIVE(vm->stringClass->obj.classObj, "fromCodePoint(_)", string_fromCodePoint); PRIMITIVE(vm->stringClass, "+(_)", string_plus); PRIMITIVE(vm->stringClass, "[_]", string_subscript); PRIMITIVE(vm->stringClass, "byteAt_(_)", string_byteAt); PRIMITIVE(vm->stringClass, "byteCount_", string_byteCount); PRIMITIVE(vm->stringClass, "codePointAt_(_)", string_codePointAt); PRIMITIVE(vm->stringClass, "contains(_)", string_contains); PRIMITIVE(vm->stringClass, "endsWith(_)", string_endsWith); PRIMITIVE(vm->stringClass, "indexOf(_)", string_indexOf); PRIMITIVE(vm->stringClass, "iterate(_)", string_iterate); PRIMITIVE(vm->stringClass, "iterateByte_(_)", string_iterateByte); PRIMITIVE(vm->stringClass, "iteratorValue(_)", string_iteratorValue); PRIMITIVE(vm->stringClass, "startsWith(_)", string_startsWith); PRIMITIVE(vm->stringClass, "toString", string_toString); vm->listClass = AS_CLASS(wrenFindVariable(vm, coreModule, "List")); PRIMITIVE(vm->listClass->obj.classObj, "new()", list_new); PRIMITIVE(vm->listClass, "[_]", list_subscript); PRIMITIVE(vm->listClass, "[_]=(_)", list_subscriptSetter); PRIMITIVE(vm->listClass, "add(_)", list_add); PRIMITIVE(vm->listClass, "addCore_(_)", list_addCore); PRIMITIVE(vm->listClass, "clear()", list_clear); PRIMITIVE(vm->listClass, "count", list_count); PRIMITIVE(vm->listClass, "insert(_,_)", list_insert); PRIMITIVE(vm->listClass, "iterate(_)", list_iterate); PRIMITIVE(vm->listClass, "iteratorValue(_)", list_iteratorValue); PRIMITIVE(vm->listClass, "removeAt(_)", list_removeAt); vm->mapClass = AS_CLASS(wrenFindVariable(vm, coreModule, "Map")); PRIMITIVE(vm->mapClass->obj.classObj, "new()", map_new); PRIMITIVE(vm->mapClass, "[_]", map_subscript); PRIMITIVE(vm->mapClass, "[_]=(_)", map_subscriptSetter); PRIMITIVE(vm->mapClass, "addCore_(_,_)", map_addCore); PRIMITIVE(vm->mapClass, "clear()", map_clear); PRIMITIVE(vm->mapClass, "containsKey(_)", map_containsKey); PRIMITIVE(vm->mapClass, "count", map_count); PRIMITIVE(vm->mapClass, "remove(_)", map_remove); PRIMITIVE(vm->mapClass, "iterate_(_)", map_iterate); PRIMITIVE(vm->mapClass, "keyIteratorValue_(_)", map_keyIteratorValue); PRIMITIVE(vm->mapClass, "valueIteratorValue_(_)", map_valueIteratorValue); vm->rangeClass = AS_CLASS(wrenFindVariable(vm, coreModule, "Range")); PRIMITIVE(vm->rangeClass, "from", range_from); PRIMITIVE(vm->rangeClass, "to", range_to); PRIMITIVE(vm->rangeClass, "min", range_min); PRIMITIVE(vm->rangeClass, "max", range_max); PRIMITIVE(vm->rangeClass, "isInclusive", range_isInclusive); PRIMITIVE(vm->rangeClass, "iterate(_)", range_iterate); PRIMITIVE(vm->rangeClass, "iteratorValue(_)", range_iteratorValue); PRIMITIVE(vm->rangeClass, "toString", range_toString); ObjClass* systemClass = AS_CLASS(wrenFindVariable(vm, coreModule, "System")); PRIMITIVE(systemClass->obj.classObj, "clock", system_clock); PRIMITIVE(systemClass->obj.classObj, "gc()", system_gc); // TODO: Do we want to give these magic names that can't be called from // regular code? PRIMITIVE(systemClass->obj.classObj, "getModuleVariable(_,_)", system_getModuleVariable); PRIMITIVE(systemClass->obj.classObj, "importModule(_)", system_importModule); PRIMITIVE(systemClass->obj.classObj, "writeString_(_)", system_writeString); // While bootstrapping the core types and running the core module, a number // of string objects have been created, many of which were instantiated // before stringClass was stored in the VM. Some of them *must* be created // first -- the ObjClass for string itself has a reference to the ObjString // for its name. // // These all currently have a NULL classObj pointer, so go back and assign // them now that the string class is known. for (Obj* obj = vm->first; obj != NULL; obj = obj->next) { if (obj->type == OBJ_STRING) obj->classObj = vm->stringClass; } }
static ModulePtr makePrimitivesModule() { ModulePtr prims = new Module("__primitives__"); addPrim(prims, "Bool", boolType.ptr()); addPrim(prims, "Int8", int8Type.ptr()); addPrim(prims, "Int16", int16Type.ptr()); addPrim(prims, "Int32", int32Type.ptr()); addPrim(prims, "Int64", int64Type.ptr()); addPrim(prims, "Int128", int128Type.ptr()); addPrim(prims, "UInt8", uint8Type.ptr()); addPrim(prims, "UInt16", uint16Type.ptr()); addPrim(prims, "UInt32", uint32Type.ptr()); addPrim(prims, "UInt64", uint64Type.ptr()); addPrim(prims, "UInt128", uint128Type.ptr()); addPrim(prims, "Float32", float32Type.ptr()); addPrim(prims, "Float64", float64Type.ptr()); addPrim(prims, "Float80", float80Type.ptr()); addPrim(prims, "Imag32", imag32Type.ptr()); addPrim(prims, "Imag64", imag64Type.ptr()); addPrim(prims, "Imag80", imag80Type.ptr()); addPrim(prims, "Complex32", complex32Type.ptr()); addPrim(prims, "Complex64", complex64Type.ptr()); addPrim(prims, "Complex80", complex80Type.ptr()); GlobalAliasPtr v = new GlobalAlias(prims.ptr(), Identifier::get("ExceptionsEnabled?"), PUBLIC, vector<PatternVar>(), NULL, vector<IdentifierPtr>(), NULL, new BoolLiteral(exceptionsEnabled())); addPrim(prims, "ExceptionsEnabled?", v.ptr()); vector<IdentifierPtr> recordParams; RecordBodyPtr recordBody = new RecordBody(vector<RecordFieldPtr>()); recordParams.push_back(Identifier::get("T")); RecordDeclPtr byRefRecord = new RecordDecl( prims.ptr(), Identifier::get("ByRef"), PUBLIC, vector<PatternVar>(), NULL, recordParams, NULL, recordBody); byRefRecord->env = new Env(prims); addPrim(prims, "ByRef", byRefRecord.ptr()); recordParams.clear(); recordParams.push_back(Identifier::get("Properties")); recordParams.push_back(Identifier::get("Fields")); RecordDeclPtr rwpRecord = new RecordDecl( prims.ptr(), Identifier::get("RecordWithProperties"), PUBLIC, vector<PatternVar>(), NULL, recordParams, NULL, recordBody); rwpRecord->env = new Env(prims); addPrim(prims, "RecordWithProperties", rwpRecord.ptr()); #define PRIMITIVE(x) addPrimOp(prims, toPrimStr(#x), new PrimOp(PRIM_##x)) PRIMITIVE(TypeP); PRIMITIVE(TypeSize); PRIMITIVE(TypeAlignment); PRIMITIVE(SymbolP); PRIMITIVE(StaticCallDefinedP); PRIMITIVE(StaticCallOutputTypes); PRIMITIVE(StaticMonoP); PRIMITIVE(StaticMonoInputTypes); PRIMITIVE(bitcopy); PRIMITIVE(bitcast); PRIMITIVE(boolNot); PRIMITIVE(integerEqualsP); PRIMITIVE(integerLesserP); PRIMITIVE(numericAdd); PRIMITIVE(numericSubtract); PRIMITIVE(numericMultiply); PRIMITIVE(floatDivide); PRIMITIVE(numericNegate); PRIMITIVE(integerQuotient); PRIMITIVE(integerRemainder); PRIMITIVE(integerShiftLeft); PRIMITIVE(integerShiftRight); PRIMITIVE(integerBitwiseAnd); PRIMITIVE(integerBitwiseOr); PRIMITIVE(integerBitwiseXor); PRIMITIVE(integerBitwiseNot); PRIMITIVE(numericConvert); PRIMITIVE(integerAddChecked); PRIMITIVE(integerSubtractChecked); PRIMITIVE(integerMultiplyChecked); PRIMITIVE(integerQuotientChecked); PRIMITIVE(integerRemainderChecked); PRIMITIVE(integerShiftLeftChecked); PRIMITIVE(integerNegateChecked); PRIMITIVE(integerConvertChecked); PRIMITIVE(floatOrderedEqualsP); PRIMITIVE(floatOrderedLesserP); PRIMITIVE(floatOrderedLesserEqualsP); PRIMITIVE(floatOrderedGreaterP); PRIMITIVE(floatOrderedGreaterEqualsP); PRIMITIVE(floatOrderedNotEqualsP); PRIMITIVE(floatOrderedP); PRIMITIVE(floatUnorderedEqualsP); PRIMITIVE(floatUnorderedLesserP); PRIMITIVE(floatUnorderedLesserEqualsP); PRIMITIVE(floatUnorderedGreaterP); PRIMITIVE(floatUnorderedGreaterEqualsP); PRIMITIVE(floatUnorderedNotEqualsP); PRIMITIVE(floatUnorderedP); PRIMITIVE(Pointer); PRIMITIVE(addressOf); PRIMITIVE(pointerDereference); PRIMITIVE(pointerOffset); PRIMITIVE(pointerToInt); PRIMITIVE(intToPointer); PRIMITIVE(nullPointer); PRIMITIVE(CodePointer); PRIMITIVE(makeCodePointer); PRIMITIVE(AttributeStdCall); PRIMITIVE(AttributeFastCall); PRIMITIVE(AttributeCCall); PRIMITIVE(AttributeThisCall); PRIMITIVE(AttributeLLVMCall); PRIMITIVE(AttributeDLLImport); PRIMITIVE(AttributeDLLExport); PRIMITIVE(ExternalCodePointer); PRIMITIVE(makeExternalCodePointer); PRIMITIVE(callExternalCodePointer); PRIMITIVE(Array); PRIMITIVE(arrayRef); PRIMITIVE(arrayElements); PRIMITIVE(Vec); PRIMITIVE(Tuple); PRIMITIVE(TupleElementCount); PRIMITIVE(tupleRef); PRIMITIVE(tupleElements); PRIMITIVE(Union); PRIMITIVE(UnionMemberCount); PRIMITIVE(RecordP); PRIMITIVE(RecordFieldCount); PRIMITIVE(RecordFieldName); PRIMITIVE(RecordWithFieldP); PRIMITIVE(recordFieldRef); PRIMITIVE(recordFieldRefByName); PRIMITIVE(recordFields); PRIMITIVE(recordVariadicField); PRIMITIVE(VariantP); PRIMITIVE(VariantMemberIndex); PRIMITIVE(VariantMemberCount); PRIMITIVE(VariantMembers); PRIMITIVE(variantRepr); PRIMITIVE(BaseType); PRIMITIVE(Static); PRIMITIVE(StaticName); PRIMITIVE(staticIntegers); PRIMITIVE(integers); PRIMITIVE(staticFieldRef); PRIMITIVE(MainModule); PRIMITIVE(StaticModule); PRIMITIVE(ModuleName); PRIMITIVE(ModuleMemberNames); PRIMITIVE(EnumP); PRIMITIVE(EnumMemberCount); PRIMITIVE(EnumMemberName); PRIMITIVE(enumToInt); PRIMITIVE(intToEnum); PRIMITIVE(StringLiteralP); PRIMITIVE(stringLiteralByteIndex); PRIMITIVE(stringLiteralBytes); PRIMITIVE(stringLiteralByteSize); PRIMITIVE(stringLiteralByteSlice); PRIMITIVE(stringLiteralConcat); PRIMITIVE(stringLiteralFromBytes); PRIMITIVE(stringTableConstant); PRIMITIVE(OrderUnordered); PRIMITIVE(OrderMonotonic); PRIMITIVE(OrderAcquire); PRIMITIVE(OrderRelease); PRIMITIVE(OrderAcqRel); PRIMITIVE(OrderSeqCst); PRIMITIVE(FlagP); PRIMITIVE(Flag); PRIMITIVE(atomicFence); PRIMITIVE(atomicRMW); PRIMITIVE(atomicLoad); PRIMITIVE(atomicStore); PRIMITIVE(atomicCompareExchange); PRIMITIVE(RMWXchg); PRIMITIVE(RMWAdd); PRIMITIVE(RMWSubtract); PRIMITIVE(RMWAnd); PRIMITIVE(RMWNAnd); PRIMITIVE(RMWOr); PRIMITIVE(RMWXor); PRIMITIVE(RMWMin); PRIMITIVE(RMWMax); PRIMITIVE(RMWUMin); PRIMITIVE(RMWUMax); PRIMITIVE(activeException); PRIMITIVE(memcpy); PRIMITIVE(memmove); PRIMITIVE(countValues); PRIMITIVE(nthValue); PRIMITIVE(withoutNthValue); PRIMITIVE(takeValues); PRIMITIVE(dropValues); PRIMITIVE(LambdaRecordP); PRIMITIVE(LambdaSymbolP); PRIMITIVE(LambdaMonoP); PRIMITIVE(LambdaMonoInputTypes); PRIMITIVE(GetOverload); PRIMITIVE(usuallyEquals); #undef PRIMITIVE return prims; }