diff --git a/docs/vm-arch/INTRINSICS.csv b/docs/vm-arch/INTRINSICS.csv index 74b3d3ef..33779d1e 100644 --- a/docs/vm-arch/INTRINSICS.csv +++ b/docs/vm-arch/INTRINSICS.csv @@ -1,6 +1,25 @@ final_id_hex,final_id_dec,canonical_name,canonical_version,owner,name,arg_slots,ret_slots,arg_layout,ret_layout,deterministic,may_allocate 0x1000,4096,vec2.dot,1,vec2,dot,4,1,float|float|float|float,float,true,false 0x1001,4097,vec2.length,1,vec2,length,2,1,float|float,float,true,false +0x1100,4352,color.from_raw,1,color,from_raw,1,1,int,builtin:color,true,false +0x1101,4353,color.rgb,1,color,rgb,3,1,int|int|int,builtin:color,true,false +0x1102,4354,color.rgba,1,color,rgba,4,1,int|int|int|int,builtin:color,true,false +0x1103,4355,color.html_rgba,1,color,html_rgba,1,1,str,builtin:color,true,false +0x1104,4356,color.gray_scale,1,color,gray_scale,1,1,int,builtin:color,true,false +0x1105,4357,color.hex,1,color,hex,1,1,builtin:color,int,true,false +0x1106,4358,color.alpha,1,color,alpha,1,1,builtin:color,int,true,false +0x1120,4384,color.black,1,color,black,0,1,,builtin:color,true,false +0x1121,4385,color.white,1,color,white,0,1,,builtin:color,true,false +0x1122,4386,color.red,1,color,red,0,1,,builtin:color,true,false +0x1123,4387,color.green,1,color,green,0,1,,builtin:color,true,false +0x1124,4388,color.blue,1,color,blue,0,1,,builtin:color,true,false +0x1125,4389,color.yellow,1,color,yellow,0,1,,builtin:color,true,false +0x1126,4390,color.orange,1,color,orange,0,1,,builtin:color,true,false +0x1127,4391,color.indigo,1,color,indigo,0,1,,builtin:color,true,false +0x1128,4392,color.gray,1,color,gray,0,1,,builtin:color,true,false +0x1129,4393,color.cyan,1,color,cyan,0,1,,builtin:color,true,false +0x112A,4394,color.magenta,1,color,magenta,0,1,,builtin:color,true,false +0x112B,4395,color.transparent,1,color,transparent,0,1,,builtin:color,true,false 0x2000,8192,input.pad,1,input,pad,0,1,,builtin:input.pad,true,false 0x2001,8193,input.touch,1,input,touch,0,1,,builtin:input.touch,true,false 0x2010,8208,input.pad.up,1,input.pad,up,1,1,builtin:input.pad,builtin:input.button,true,false diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableBodyLowerer.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableBodyLowerer.java index ef40fb11..eb3af2d1 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableBodyLowerer.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableBodyLowerer.java @@ -574,7 +574,30 @@ final class PbsExecutableBodyLowerer { final var constDecl = context.resolveConstDecl(identifierExpr.name()); if (constDecl != null && constDecl.initializer() != null) { lowerConstExpression(constDecl.initializer(), context); + return; } + final var builtinConst = context.builtinConstByNameId().get(context.nameTable().register(identifierExpr.name())); + if (builtinConst != null) { + emitBuiltinConstFetch(builtinConst, identifierExpr.span(), context); + } + } + + private void emitBuiltinConstFetch( + final p.studio.compiler.models.IRReservedMetadata.BuiltinConstSurface builtinConst, + final p.studio.compiler.source.Span span, + final PbsExecutableLoweringContext context) { + final var canonicalName = builtinConst.canonicalTarget() + "." + builtinConst.canonicalName(); + context.instructions().add(new IRBackendExecutableFunction.Instruction( + IRBackendExecutableFunction.InstructionKind.CALL_INTRINSIC, + "", + null, + new IRBackendExecutableFunction.IntrinsicCallMetadata( + canonicalName, + builtinConst.canonicalVersion(), + context.intrinsicIdTable().register(canonicalName, builtinConst.canonicalVersion())), + 0, + 1, + span)); } private String flattenAssetReference(final PbsAst.Expression expression) { diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableCallsiteEmitter.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableCallsiteEmitter.java index b818c3d8..5eed818e 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableCallsiteEmitter.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableCallsiteEmitter.java @@ -326,6 +326,10 @@ final class PbsExecutableCallsiteEmitter { if (!localOwner.isBlank()) { return localOwner; } + final var builtinOwner = context.builtinCanonicalBySourceType().getOrDefault(identifier, ""); + if (!builtinOwner.isBlank()) { + return builtinOwner; + } return context.builtinConstOwnerByNameId().getOrDefault(context.nameTable().register(identifier), ""); } diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableLoweringContext.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableLoweringContext.java index 5d67b552..702d1b51 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableLoweringContext.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableLoweringContext.java @@ -60,6 +60,10 @@ final class PbsExecutableLoweringContext { return metadataIndex.builtinConstOwnerByNameId(); } + Map builtinConstByNameId() { + return metadataIndex.builtinConstByNameId(); + } + Map globalSlotByNameId() { return metadataIndex.globalSlotByNameId(); } diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableLoweringModels.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableLoweringModels.java index b937ea97..9bacacc0 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableLoweringModels.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableLoweringModels.java @@ -45,6 +45,7 @@ public class PbsExecutableLoweringModels { Map> hostByMethodName, Map builtinCanonicalBySourceType, Map builtinConstOwnerByNameId, + Map builtinConstByNameId, Map globalSlotByNameId, Map constDeclByNameId, Map addressableByAddress, diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableMetadataIndexFactory.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableMetadataIndexFactory.java index 978efae2..ddfaa5f1 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableMetadataIndexFactory.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/lowering/PbsExecutableMetadataIndexFactory.java @@ -30,6 +30,7 @@ final class PbsExecutableMetadataIndexFactory { final var hostByMethodName = indexHostBindingsByMethodName(reservedMetadata, nameTable); final var builtinCanonicalBySourceType = indexBuiltinCanonicalBySourceType(reservedMetadata); final var builtinConstOwnerByNameId = indexBuiltinConstOwners(reservedMetadata, nameTable); + final var builtinConstByNameId = indexBuiltinConstSurfaces(reservedMetadata, nameTable); final var globalSlotByNameId = indexGlobalSlots(ast, nameTable); final var constDeclByNameId = indexConstDecls(ast, nameTable); final var addressableByAddress = indexAddressables(feSurfaceContext); @@ -50,6 +51,7 @@ final class PbsExecutableMetadataIndexFactory { hostByMethodName, builtinCanonicalBySourceType, builtinConstOwnerByNameId, + builtinConstByNameId, globalSlotByNameId, constDeclByNameId, addressableByAddress, @@ -90,6 +92,19 @@ final class PbsExecutableMetadataIndexFactory { return builtinConstOwnerByNameId; } + private Map indexBuiltinConstSurfaces( + final IRReservedMetadata reservedMetadata, + final NameTable nameTable) { + final var builtinConstByNameId = new HashMap(); + for (final var builtinConst : reservedMetadata.builtinConstSurfaces()) { + if (builtinConst.sourceConstName().isBlank() || builtinConst.canonicalTarget().isBlank()) { + continue; + } + builtinConstByNameId.put(nameTable.register(builtinConst.sourceConstName()), builtinConst); + } + return builtinConstByNameId; + } + private Map indexGlobalSlots( final PbsAst.File ast, final NameTable nameTable) { diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowCallableResolutionAnalyzer.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowCallableResolutionAnalyzer.java index 9be1c815..f1a4b8e6 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowCallableResolutionAnalyzer.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowCallableResolutionAnalyzer.java @@ -86,6 +86,22 @@ final class PbsFlowCallableResolutionAnalyzer { if (enumCases != null && enumCases.contains(memberExpr.memberName())) { return ExprResult.type(TypeView.enumType(receiver.name())); } + if (model.knownBuiltinTypeNames.contains(receiver.name())) { + final var builtin = model.structs.get(receiver.name()); + if (builtin != null) { + final var methods = builtin.methods().get(memberExpr.memberName()); + if (methods != null && !methods.isEmpty()) { + if (use == ExprUse.VALUE) { + Diagnostics.error(diagnostics, + PbsSemanticsErrors.E_SEM_BARE_METHOD_EXTRACTION.name(), + "Bare method extraction is not allowed in PBS core", + memberExpr.span()); + return ExprResult.type(TypeView.unknown()); + } + return ExprResult.callables(methods, true); + } + } + } Diagnostics.error(diagnostics, PbsSemanticsErrors.E_SEM_INVALID_MEMBER_ACCESS.name(), "Invalid type member access", diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowSemanticSupport.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowSemanticSupport.java index 1110664a..668f6b74 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowSemanticSupport.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowSemanticSupport.java @@ -191,6 +191,7 @@ final class PbsFlowSemanticSupport { final Map constTypes = new HashMap<>(); final Map globalTypes = new HashMap<>(); final Map serviceSingletons = new HashMap<>(); + final Set knownBuiltinTypeNames = new HashSet<>(); final Set knownStructNames = new HashSet<>(); final Set knownServiceNames = new HashSet<>(); final Set knownContractNames = new HashSet<>(); @@ -232,6 +233,7 @@ final class PbsFlowSemanticSupport { return; } if (topDecl instanceof PbsAst.BuiltinTypeDecl builtinTypeDecl) { + knownBuiltinTypeNames.add(builtinTypeDecl.name()); knownStructNames.add(builtinTypeDecl.name()); return; } diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowStructuralExpressionAnalyzer.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowStructuralExpressionAnalyzer.java index 618969fb..ee4f7126 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowStructuralExpressionAnalyzer.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowStructuralExpressionAnalyzer.java @@ -108,6 +108,10 @@ final class PbsFlowStructuralExpressionAnalyzer { return ExprResult.type(TypeView.typeRef(identifierExpr.name())); } + if (model.knownBuiltinTypeNames.contains(identifierExpr.name())) { + return ExprResult.type(TypeView.typeRef(identifierExpr.name())); + } + return ExprResult.type(TypeView.unknown()); } if (expression instanceof PbsAst.GroupExpr groupExpr) { diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/resources/game/stdlib/1/core/color/main.pbs b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/resources/game/stdlib/1/core/color/main.pbs index 70c87c0d..103de9ab 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/resources/game/stdlib/1/core/color/main.pbs +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/resources/game/stdlib/1/core/color/main.pbs @@ -1,5 +1,61 @@ -[BuiltinType(name = "Color", version = 1)] +[BuiltinType(name = "color", version = 1)] declare builtin type Color( pub raw: int ) { + [IntrinsicCall(name = "from_raw", version = 1)] + fn from_raw(raw: int) -> Color; + + [IntrinsicCall(name = "rgb", version = 1)] + fn rgb(r: int, g: int, b: int) -> Color; + + [IntrinsicCall(name = "rgba", version = 1)] + fn rgba(r: int, g: int, b: int, a: int) -> Color; + + [IntrinsicCall(name = "html_rgba", version = 1)] + fn html_rgba(value: str) -> Color; + + [IntrinsicCall(name = "gray_scale", version = 1)] + fn gray_scale(value: int) -> Color; + + [IntrinsicCall(name = "hex", version = 1)] + fn hex() -> int; + + [IntrinsicCall(name = "alpha", version = 1)] + fn alpha() -> int; } + +[BuiltinConst(target = "color", name = "black", version = 1)] +declare const BLACK: Color; + +[BuiltinConst(target = "color", name = "white", version = 1)] +declare const WHITE: Color; + +[BuiltinConst(target = "color", name = "red", version = 1)] +declare const RED: Color; + +[BuiltinConst(target = "color", name = "green", version = 1)] +declare const GREEN: Color; + +[BuiltinConst(target = "color", name = "blue", version = 1)] +declare const BLUE: Color; + +[BuiltinConst(target = "color", name = "yellow", version = 1)] +declare const YELLOW: Color; + +[BuiltinConst(target = "color", name = "orange", version = 1)] +declare const ORANGE: Color; + +[BuiltinConst(target = "color", name = "indigo", version = 1)] +declare const INDIGO: Color; + +[BuiltinConst(target = "color", name = "gray", version = 1)] +declare const GRAY: Color; + +[BuiltinConst(target = "color", name = "cyan", version = 1)] +declare const CYAN: Color; + +[BuiltinConst(target = "color", name = "magenta", version = 1)] +declare const MAGENTA: Color; + +[BuiltinConst(target = "color", name = "transparent", version = 1)] +declare const TRANSPARENT: Color; diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/resources/game/stdlib/1/core/color/mod.barrel b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/resources/game/stdlib/1/core/color/mod.barrel index c7bfb43f..7c52c59d 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/resources/game/stdlib/1/core/color/mod.barrel +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/resources/game/stdlib/1/core/color/mod.barrel @@ -1 +1,13 @@ pub struct Color; +pub const BLACK; +pub const WHITE; +pub const RED; +pub const GREEN; +pub const BLUE; +pub const YELLOW; +pub const ORANGE; +pub const INDIGO; +pub const GRAY; +pub const CYAN; +pub const MAGENTA; +pub const TRANSPARENT; diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/test/java/p/studio/compiler/services/PBSFrontendPhaseServiceTest.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/test/java/p/studio/compiler/services/PBSFrontendPhaseServiceTest.java index caaca820..b97b9c88 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/test/java/p/studio/compiler/services/PBSFrontendPhaseServiceTest.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/test/java/p/studio/compiler/services/PBSFrontendPhaseServiceTest.java @@ -1019,6 +1019,74 @@ class PBSFrontendPhaseServiceTest { assertTrue(irBackend.getExecutableFunctions().stream().anyMatch(function -> "frame".equals(function.callableName()))); } + @Test + void shouldLowerCoreColorConstructorsAndConstantsFromBootstrapStdlib() throws IOException { + final var projectRoot = tempDir.resolve("project-bootstrap-core-color-rgba"); + final var sourceRoot = projectRoot.resolve("src"); + final var modulePath = sourceRoot.resolve("app"); + Files.createDirectories(modulePath); + + final var sourceFile = modulePath.resolve("source.pbs"); + final var modBarrel = modulePath.resolve("mod.barrel"); + Files.writeString(sourceFile, """ + import { Color, RED, TRANSPARENT } from @core:color; + import { Gfx } from @sdk:gfx; + + [Frame] + fn frame() -> void + { + let tint: Color = Color.rgba(1, 2, 3, 128); + let web: Color = Color.html_rgba("#11223344"); + Gfx.clear(RED); + Gfx.fill_rect(0, 0, 1, 1, tint); + Gfx.fill_rect(1, 0, 1, 1, web); + Gfx.fill_rect(2, 0, 1, 1, TRANSPARENT); + } + """); + Files.writeString(modBarrel, "pub fn frame() -> void;"); + + final var projectTable = new ProjectTable(); + final var fileTable = new FileTable(1); + final var projectId = projectTable.register(ProjectDescriptor.builder() + .rootPath(projectRoot) + .name("app") + .version("1.0.0") + .sourceRoots(ReadOnlyList.wrap(List.of(sourceRoot))) + .build()); + + registerFile(projectId, projectRoot, sourceFile, fileTable); + registerFile(projectId, projectRoot, modBarrel, fileTable); + + final var ctx = new FrontendPhaseContext( + projectTable, + fileTable, + new BuildStack(ReadOnlyList.wrap(List.of(projectId))), + 1, + AppMode.Game); + final var diagnostics = DiagnosticSink.empty(); + + final var irBackend = new PBSFrontendPhaseService().compile( + ctx, + diagnostics, + LogAggregator.empty(), + BuildingIssueSink.empty()); + + assertFalse(diagnostics.hasErrors(), + "diagnostics=" + diagnostics.stream().map(d -> d.getCode() + ":" + d.getMessage()).toList()); + assertTrue(diagnostics.stream().noneMatch(d -> + d.getCode().equals(PbsSemanticsErrors.E_SEM_EXEC_LOWERING_UNRESOLVED_CALLEE.name())), + "diagnostics=" + diagnostics.stream().map(d -> d.getCode() + ":" + d.getMessage()).toList()); + final var intrinsicNames = irBackend.getExecutableFunctions().stream() + .flatMap(function -> function.instructions().stream()) + .filter(instruction -> instruction.kind() == IRBackendExecutableFunction.InstructionKind.CALL_INTRINSIC) + .map(instruction -> instruction.intrinsicCall().canonicalName()) + .toList(); + assertTrue(intrinsicNames.contains("color.rgba"), "intrinsics=" + intrinsicNames); + assertTrue(intrinsicNames.contains("color.html_rgba"), "intrinsics=" + intrinsicNames); + assertTrue(intrinsicNames.contains("color.red"), "intrinsics=" + intrinsicNames); + assertTrue(intrinsicNames.contains("color.transparent"), "intrinsics=" + intrinsicNames); + } + @Test void shouldLowerSdkComposerEmitSpriteFacadeUsingCanonicalComposerContract() throws IOException { final var projectRoot = tempDir.resolve("project-bootstrap-sdk-composer-emit-sprite"); diff --git a/prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/backend/irvm/IRVMIntrinsicDefinition.java b/prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/backend/irvm/IRVMIntrinsicDefinition.java index 7bb916fa..36ad35a5 100644 --- a/prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/backend/irvm/IRVMIntrinsicDefinition.java +++ b/prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/backend/irvm/IRVMIntrinsicDefinition.java @@ -5,6 +5,25 @@ import java.util.Objects; enum IRVMIntrinsicDefinition { VEC2_DOT("vec2.dot", 1, 0x1000, "vec2", "dot", 4, 1, "float|float|float|float", "float", true, false), VEC2_LENGTH("vec2.length", 1, 0x1001, "vec2", "length", 2, 1, "float|float", "float", true, false), + COLOR_FROM_RAW("color.from_raw", 1, 0x1100, "color", "from_raw", 1, 1, "int", "builtin:color", true, false), + COLOR_RGB("color.rgb", 1, 0x1101, "color", "rgb", 3, 1, "int|int|int", "builtin:color", true, false), + COLOR_RGBA("color.rgba", 1, 0x1102, "color", "rgba", 4, 1, "int|int|int|int", "builtin:color", true, false), + COLOR_HTML_RGBA("color.html_rgba", 1, 0x1103, "color", "html_rgba", 1, 1, "str", "builtin:color", true, false), + COLOR_GRAY_SCALE("color.gray_scale", 1, 0x1104, "color", "gray_scale", 1, 1, "int", "builtin:color", true, false), + COLOR_HEX("color.hex", 1, 0x1105, "color", "hex", 1, 1, "builtin:color", "int", true, false), + COLOR_ALPHA("color.alpha", 1, 0x1106, "color", "alpha", 1, 1, "builtin:color", "int", true, false), + COLOR_BLACK("color.black", 1, 0x1120, "color", "black", 0, 1, "", "builtin:color", true, false), + COLOR_WHITE("color.white", 1, 0x1121, "color", "white", 0, 1, "", "builtin:color", true, false), + COLOR_RED("color.red", 1, 0x1122, "color", "red", 0, 1, "", "builtin:color", true, false), + COLOR_GREEN("color.green", 1, 0x1123, "color", "green", 0, 1, "", "builtin:color", true, false), + COLOR_BLUE("color.blue", 1, 0x1124, "color", "blue", 0, 1, "", "builtin:color", true, false), + COLOR_YELLOW("color.yellow", 1, 0x1125, "color", "yellow", 0, 1, "", "builtin:color", true, false), + COLOR_ORANGE("color.orange", 1, 0x1126, "color", "orange", 0, 1, "", "builtin:color", true, false), + COLOR_INDIGO("color.indigo", 1, 0x1127, "color", "indigo", 0, 1, "", "builtin:color", true, false), + COLOR_GRAY("color.gray", 1, 0x1128, "color", "gray", 0, 1, "", "builtin:color", true, false), + COLOR_CYAN("color.cyan", 1, 0x1129, "color", "cyan", 0, 1, "", "builtin:color", true, false), + COLOR_MAGENTA("color.magenta", 1, 0x112A, "color", "magenta", 0, 1, "", "builtin:color", true, false), + COLOR_TRANSPARENT("color.transparent", 1, 0x112B, "color", "transparent", 0, 1, "", "builtin:color", true, false), INPUT_PAD("input.pad", 1, 0x2000, "input", "pad", 0, 1, "", "builtin:input.pad", true, false), INPUT_TOUCH("input.touch", 1, 0x2001, "input", "touch", 0, 1, "", "builtin:input.touch", true, false), INPUT_PAD_UP("input.pad.up", 1, 0x2010, "input.pad", "up", 1, 1, "builtin:input.pad", "builtin:input.button", true, false),