Skip to content

Instantly share code, notes, and snippets.

@joseoliv
Last active August 30, 2022 11:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joseoliv/7c4cd217d20bec33e6c5fbf74c5e121c to your computer and use it in GitHub Desktop.
Save joseoliv/7c4cd217d20bec33e6c5fbf74c5e121c to your computer and use it in GitHub Desktop.
onFieldMissing
package metaobjectTest
@doc{*
Annotations of this metaobject should be attached to a prototype.
The attached DSL code is made in Myan, which supports interpreted Cyan
within parameterless methods declared with 'func':
func afterResTypes_codeToAdd {
// interpreted Cyan code
}
According to the method name, the Cyan code is interpreted in phase
afterResTypes or semAn. Methods of interfaces
IAction_semAn
IActionNewPrototypes_semAn
IAction_afterResTypes
IActionNewPrototypes_afterResTypes
IParseWithCyanCompiler_parsing
ICommunicateInPrototype_afterResTypes_semAn_afterSemAn
IActionFieldMissing_semAn
can be implemented. To better understand this, see the documentation
for action_afterResTypes_semAn.
*}
@onFieldMissing{*
func semAn_replaceGetMissingField {
var String name = fieldToGet asString;
if name startsWith: "self." { name = name substring: 5 }
var Int n = -1;
if name == "cyan" { n = 0; }
else if name == "red" { n = 1; }
else if name == "blue" { n = 2; }
else if name == "green" { n = 3; }
if n >= 0 {
return [. "cyan.lang", "Int", n ++ "" .];
}
// other wise, return null and there will be
// a compilation error "field not found"
}
func semAn_replaceSetMissingField {
var String name = fieldToSet asString;
if name startsWith: "self." { name = name substring: 5 }
if name == "cyan" {
// assignments to 'cyan' are replaced by
// the empty statement
return ";"
}
else {
metaobject addError: "I am very sorry, but '" ++ name
++ "' is not a field declared in this prototype";
}
}
*}
object OnFieldMissing
func run {
var cyanValue = self.cyan;
let redValue = self.red;
let blueValue = self.blue;
let greenValue = self.green;
assert cyanValue == 0;
assert redValue == 1;
assert blueValue == 2;
assert greenValue == 3;
// ok, replaced by ';'
self.cyan = 5;
cyanValue = self.cyan;
assert cyanValue == 0;
}
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment