|
|
@ -0,0 +1,80 @@ |
|
|
|
FormatString = Object.subtype(#FormatString); |
|
|
|
|
|
|
|
FormatString.new(elements) { |
|
|
|
self = super.new(); |
|
|
|
self.elements = elements; |
|
|
|
self; |
|
|
|
} |
|
|
|
|
|
|
|
FormatString.__eval__(env) { |
|
|
|
local result = ""; |
|
|
|
for(elem in self.elements) { |
|
|
|
local elemval = elem.__eval__(env); |
|
|
|
if (elemval.__name__ == #String) { |
|
|
|
result.push(elemval); |
|
|
|
} else { |
|
|
|
elemval.__codeon__(result); |
|
|
|
} |
|
|
|
} |
|
|
|
result; |
|
|
|
} |
|
|
|
|
|
|
|
FormatString.__codeon__(str) { |
|
|
|
str.push("f\""); |
|
|
|
for(elem in self.elements) { |
|
|
|
if (elem.__name__ == #String) { |
|
|
|
str.push(elem.escaped()); |
|
|
|
} else { |
|
|
|
str.push("$"); |
|
|
|
elem.__codeon__(str); |
|
|
|
} |
|
|
|
} |
|
|
|
str.push("\""); |
|
|
|
} |
|
|
|
|
|
|
|
__namespaces__.metaLanguage.primary.prepend("fstring"); |
|
|
|
|
|
|
|
nonSpaceEatingId = parseDefinition( |
|
|
|
"nonSpaceEatingId = < LETTER ALNUM* > { intern(yytext) } |
|
|
|
"); |
|
|
|
|
|
|
|
nonSpaceEatingBlock = parseDefinition( |
|
|
|
"nonSpaceEatingBlock = LBRACE b:mkobj |
|
|
|
( e:stmt { b.push(e) } |
|
|
|
)* \"}\" { b } |
|
|
|
"); |
|
|
|
|
|
|
|
fStringChar = parseDefinition( |
|
|
|
"fStringChar = < (!\"\\\"\" !\"$\" char )+ > { yytext } |
|
|
|
| \"\\\\$\" { \"$\" } |
|
|
|
"); |
|
|
|
|
|
|
|
fStringRule = parseDefinition( |
|
|
|
"fstring = \"f\\\"\" elements:mkobj |
|
|
|
( \"$\" i:nonSpaceEatingId { elements.push(GetVar.new(name: i)) } |
|
|
|
| \"$\" b:nonSpaceEatingBlock { elements.push(Block.new(body: b)) } |
|
|
|
| c:fStringChar { elements.push(c) } |
|
|
|
)* \"\\\"\" { FormatString.new(elements) } |
|
|
|
"); |
|
|
|
|
|
|
|
// regenerate the expression to be executed |
|
|
|
metaLanguage.addRule(nonSpaceEatingBlock.name, nonSpaceEatingBlock.expression); |
|
|
|
metaLanguage.addRule(nonSpaceEatingId.name, nonSpaceEatingId.expression); |
|
|
|
metaLanguage.addRule(fStringChar.name, fStringChar.expression); |
|
|
|
metaLanguage.addRule(fStringRule.name, fStringRule.expression); |
|
|
|
metaLanguage.addRule(#primary, __namespaces__.metaLanguage.primary); |
|
|
|
|
|
|
|
formatInt(integer) { |
|
|
|
if (integer > 1000) { |
|
|
|
return f"${formatInt((integer - integer % 1000) / 1000)},${integer % 1000}"; |
|
|
|
} |
|
|
|
return f"$integer"; |
|
|
|
} |
|
|
|
a = 69; |
|
|
|
print(f"Reimu has $a power and ${6*7} point items and \$${ formatInt(1 << 24) } money.\n"); |
|
|
|
n = 100; |
|
|
|
print(f"Sum of integers from 1 to $n : ${local sum = 0; for (i in n + 1) sum += i}\n"); |
|
|
|
print(f"${formatInt.function}\n"); |
|
|
|
//{ |
|
|
|
// print(f"${__env__()}\n"); |
|
|
|
//} |