ã¯ããã«
ãã®èšäºã§ã¯ãçŽæãããšããã ãã®èšäºã§å§ãŸã£ãCoolèšèªçšã®ã³ã³ãã€ã©ãŒã®éçºã®èª¬æãç¶ããŸãã
![](https://habrastorage.org/getpro/habr/post_images/98b/3ca/ec1/98b3caec1928ce34a33e12f1a4f479be.png)
åå¥è§£æåšããã³æ§æ解æåšã¯ãæåã®èšäºã§èšåãããŸããã
ã»ãã³ãã£ãã¯ã¢ãã©ã€ã¶ãŒã®äž»ãªã¿ã¹ã¯ã¯ããœãŒã¹ããã°ã©ã ã§èšèªã®å®çŸ©ãšã®ã»ãã³ãã£ã¯ã¹ã®æŽåæ§ããã§ãã¯ããããšã§ãã ããã¯äž»ã«åãã§ã㯠ãã€ãŸã ã³ã³ãã€ã©ããåæŒç®åã«é©åãªã¿ã€ãã®ãªãã©ã³ãããããã©ããã確èªãããšãã
ãœãŒã¹ã³ãŒãã®äžéè¡šçŸãçæããã«ã¯ãäžéã³ãŒãçæãå¿ èŠã§ããäžéè¡šçŸã¯ã ç°¡åã«çæãããã¿ãŒã²ãããã·ã³èšèªã«ç°¡åã«å€æãããå¿ èŠããããŸã ã ãã®ãããªè¡šçŸãšããŠãããšãã°ã 3ã€ã®ã¢ãã¬ã¹ã³ãŒãã䜿çšãããŸãã
ãã·ã³ã«äŸåããªãã³ãŒãæé©åã®ãã§ãŒãºã¯ãäžéã³ãŒããæ¹åããããã«äœ¿çšãããŸãïŒããéãããããŸãã«ãããçãïŒã
ã³ãŒãçæãšã¯ãäžéè¡šçŸãã¢ã»ã³ãã©ãŒãŸãã¯ä»®æ³ãã·ã³ã®äžé£ã®åœä»€ã«çŽæ¥å€æããããšã§ãã
ãã·ã³äŸåã®æé©åãã§ãŒãºã¯ãã³ãŒããæé©åããããã«ã¿ãŒã²ãããã·ã³ïŒããšãã°SSE ïŒããã®ç¹å¥ãªåœä»€ã䜿çšããããšãé€ããŠã ãã·ã³ã«äŸåããªãæé©åã«äŒŒãŠããŸãã ç§ãã¡ã®å Žåããããã®è²¬ä»»ã¯CLRã«ãã£ãŠåŒãåããããããšã¯æããã§ãã
å³ãããããããã«ã1ã€ã®æ®µéã§ãå·ŠåŽã®å³ããæ倧3ã€ã®æ®µéãçµã¿åãããŸããã ããã¯ã System.Reflection.EmitããŒã«ã䜿çšããŠäžéã³ãŒããçæã§ããªãããšïŒå€æŽã§ããªãCILåœä»€ã®ã·ãŒã±ã³ã¹ãçæãããããïŒãããã³å šäœãšããŠã®èãã®æªãã¢ãŒããã¯ãã£ã«ãã£ãŠèª¬æãããŠããŸãã
建ç¯
ãããŒãã©ãããå§ããã°ããã®ãããããŸããïŒ
ã³ãŒããžã§ãã¬ãŒã¿ãŒã®æé ã説æããŸãã
- ã¯ã©ã¹å®çŸ©
- é¢æ°ãšãã£ãŒã«ãã®å®çŸ©
- ã³ã³ã¹ãã©ã¯ã¿ãŒãšé¢æ°ã³ãŒãã®çæ
ã¯ã©ã¹å®çŸ©
ã¯ãŒã«ãªãœãŒã¹ã³ãŒãã¯ã¯ã©ã¹ã®ã³ã¬ã¯ã·ã§ã³ã§ããããšãç¥ãããŠããŸãã åœç¶ã ãšã³ããªãã€ã³ããååšããå¿ èŠããããŸããååšããªãå Žåãäœãå®è¡ãããŸããã
ãããã£ãŠããšã³ããªé¢æ°ã¯Mainã¯ã©ã¹ã®ã¡ã€ã³é¢æ°ã§ãã ã¯ã©ã¹ãšé¢æ°ã®äž¡æ¹ãæåã§ç»é²ããå¿ èŠããããŸãã ããããããã«ã€ããŠã¯åŸã§è©³ãã説æããŸãã
System.Reflection.Emitã«ã¯ãåçã¢ã»ã³ããªã®æ§ç¯ãšCILã³ãŒãã®çæã«äœ¿çšãããç¹å¥ãªã¯ã©ã¹AssemblyBuilderãšModuleBuilderããããŸãã
ã¯ã©ã¹ã®èª¬æã宣èšããã«ã¯ãã¡ãœããã䜿çšããŸã
TypeBuilder ModuleBuilder.DefineType(string className, TypeAttributes attr, Type parent)
classNameã¯ã¯ã©ã¹ã®ååã attrã¯ãã®å±æ§ã parentã¯èŠªïŒããå ŽåïŒã§ãã
TypeBuilderã¯åçãªåã§ãã³ãŒããçæãããšãã«äœ¿çšãããŸãïŒããšãã°ãnewæŒç®åçšïŒã
ãã®ããããã®æ®µéã§ã¯ãäžå³ã«ç€ºãããã«ãããŒãµãŒããååŸããæ§æããªãŒã§ã¯ã©ã¹ã¿ã€ãã®ããŒãããã€ãã¹ããããœãŒã¹ã³ãŒãå ã®ãã¹ãŠã®ã¯ã©ã¹ãäžèšã®æ¹æ³ã䜿çšããŠæ±ºå®ãããŸãã
![](https://habrastorage.org/getpro/habr/post_images/bc1/bc4/6ca/bc1bc46ca4e0ee097929e46e1a2cabda.png)
èšèªã®ãªãã·ã§ã³ã®æåã¯é»è²ã§è¡šç€ºãããŸãïŒèŠªã¯ã©ã¹ã®ååã§ãã芪ããªãå Žåãã¯ã©ã¹ã¯Objectãç¶æ¿ããŸãïŒã
ãã®æ®µéã§ã¯ãã¯ã©ã¹å®çŸ©ã®ã¿ãäœæããããã®äžã®é¢æ°ãšãã£ãŒã«ãã®èª¬æã¯ãããŸããã é¢æ°ãšãã£ãŒã«ããããã«èª¬æãããšãã¯ã©ã¹ãå®çŸ©ãããŠããªããšãããšã©ãŒãçºçããå ŽåããããŸãããããã«ã€ããŠã¯åŸã§èª¬æããŸãã
ãŸããã¯ã©ã¹ãå®çŸ©ããåã«ããœãŒã¹ã³ãŒãå ã®èª¬æãæ£ããé åºã§äžŠã¹æ¿ããããšããå§ãããŸãïŒããšãã°ãAãç¶æ¿ããã¯ã©ã¹Bã®èª¬æãããã次ã«ã¯ã©ã¹Aã®èª¬æããããŸãïŒã ããããæ®å¿µãªããããã¯å®è£ ãããŠããªãããããã¹ãŠã®ã¯ã©ã¹ã¯äœ¿çšãããé åºã§èšè¿°ããå¿ èŠããããŸãã
ãããã£ãŠããã®æ®µéã§èŸæžãåä¿¡ãããŸã
Dictionary<string, TypeBuilder> ClassBuilders_;
ããã§ãããŒã¯ã¯ã©ã¹ã®ååã§ãããå€ã¯ãã®ãã«ããŒã§ãã
çµè«ãšããŠããã¹ãŠã®ã³ãŒããçæããåŸãCreateTypeã¡ãœããã䜿çšããŠåçåã確å®ããå¿ èŠããããŸãïŒããã¯FinalAllClassesé¢æ°ã§è¡ãããŸãïŒã
é¢æ°ãšãã£ãŒã«ãã®å®çŸ©
ã¯ã©ã¹ãå®çŸ©ããåŸãåã¯ã©ã¹ã§ãããã«äœ¿çšããããã«ãã®é¢æ°ãšã¡ãœããã決å®ããå¿ èŠããããŸãã ããã¯ã¡ãœããã䜿çšããŠè¡ãããŸãã
public FieldBuilder DefineField(string fieldName, Type type, FieldAttributes attributes)
ãããŠ
public MethodBuilder DefineMethod(string name, MethodAttributes attributes, Type returnType, Type[] parameterTypes);
ããã«å¿ããŠã
ãã®æ®µéã®çµããã«ãäºæ¬¡å ã®èŸæžããã£ã±ãã«ãªããŸã
protected Dictionary<string, Dictionary<string, FieldObjectDef>> Fields_; protected Dictionary<string, Dictionary<string, MethodDef>> Functions_;
æåã®æ¬¡å ã®èŸæžããŒã¯ã¯ã©ã¹ã®ååã§ã2çªç®ã¯é¢æ°ãŸãã¯ãã£ãŒã«ãã®ååã§ãã å€ã¯ããããé¢æ°èšè¿°åãŸãã¯ãã£ãŒã«ãã§ãïŒãããã®ã¯ã©ã¹ã«ã€ããŠã¯åŸã»ã©èª¬æããŸãïŒã
ãœãŒã¹ã³ãŒãå ã®é¢æ°ãšãã£ãŒã«ãã®èª¬æã䞊ã¹æ¿ããåé¡ã¯ãã¯ã©ã¹ãå®çŸ©ãããšãã®ããã«ãããã«ã¯ãããŸããã ã¯ã©ã¹å®çŸ©ã®æ®µéã§ãä»ã®ã¯ã©ã¹ã«é¢ããæ å ±ãéºäŒã決å®ããããã«äœ¿çšãããDefineTypeé¢æ°ã§çŽæ¥äœ¿çšãããããã§ãã ãã ããé¢æ°ãå®çŸ©ããããã«ä»ã®é¢æ°ã«é¢ããæ å ±ã¯å¿ èŠãªãããïŒããã§ã¯ã³ãŒãçæã¯è¡ãããŸããïŒãä»ã®é¢æ°ãžã®ãªã³ã¯ã¯å¿ èŠãããŸããã ããã¯ãé¢æ°ãšãã£ãŒã«ãã®å®çŸ©ãä»»æã®é åºã§çæã§ããããšãæå³ããŸãã
ã³ã³ã¹ãã©ã¯ã¿ãŒãšé¢æ°ã³ãŒãã®çæ
ãããŠãããã§æãèå³æ·±ãããšã«ãªããŸããã ããã§ã¯ããã¹ãŠã®ã¯ã©ã¹ã®é¢æ°æ¬äœãšã³ã³ã¹ãã©ã¯ã¿ãŒã®çŽæ¥ååž°çãªãã©ããŒãµã«ãçºçããŸãã
ãããã£ãŠãåã®æ®µéããããã¹ãŠã®ã¯ã©ã¹ã®ãã¹ãŠã®ã¡ãœããèšè¿°åïŒMethodBuilderïŒã®èŸæžãååŸãããŸããã
ã¡ãœããã«CILã¹ããŒãã¡ã³ããè¿œå ããã«ã¯ãæåã«äœ¿çšããŠç¹å¥ãªILGeneratorãªããžã§ã¯ããååŸããå¿ èŠããããŸã
var ilGenerator = methodBuilder.GetILGenerator()
ããã®ãžã§ãã¬ãŒã¿ãŒã§Emitã¡ãœããã䜿çšããŸãã
Emitã¡ãœããã«ã¯å€ãã®åœ¢åŒããããŸãã
void Emit(OpCode opcode); void Emit(OpCode opcode, int arg); void Emit(OpCode opcode, double arg); void Emit(OpCode opcode, ConstructorInfo con); void Emit(OpCode opcode, LocalBuilder local); void Emit(OpCode opcode, FieldInfo field); void Emit(OpCode opcode, MethodInfo meth); void Emit(OpCode opcode, Type cls);
OpCodeã¯ãä»®æ³.NETãã·ã³åœä»€ã§ãã 説æä»ãã®é©åãªæé ã®ãªã¹ããããã«ç€ºããŸã ã
ãããŠã2çªç®ã®åŒæ°ïŒåžžã«ååšãããšã¯éããŸããïŒã¯ãåã®2ã€ã®æ®µéã§ååŸãããã¯ã©ã¹ãŸãã¯ã¡ãœããã®ããã«ããŒããŸãã¯èšè¿°åã§ãã
çŸåšã®é¢æ°ãšçŸåšã®ã¯ã©ã¹ã¯ããããããã³ãŒããçŸåšçæãããŠããé¢æ°ãšã¯ã©ã¹ã§ãïŒæ§æããªãŒãèµ°æ»ãããšãïŒã
æåã«ãé¢æ°åŒæ°ãããŒã«ã«å€æ°ãäžæããŒã«ã«å€æ°ãããã³ã¯ã©ã¹ãã£ãŒã«ããèšè¿°ããããã«ã³ãŒããžã§ãã¬ãŒã¿ãŒã§å°å ¥ããã¯ã©ã¹ã«ã€ããŠèª¬æããŸãã åºæ¬ã¯ã©ã¹ã¯ObjectDefã§ããã察å¿ãããªããžã§ã¯ããããŒãããã³ãªãªãŒã¹ããæœè±¡ã¡ãœããLoadïŒïŒãRemoveïŒïŒãå«ãŸããŸãã
- FieldObjectDef-ä»»æã®ã¯ã©ã¹ã®ãã£ãŒã«ããèšè¿°ããããã«äœ¿çšãããŸãïŒã¯ãŒã«ãã£ãŒã«ã-ããã¯æ©èœã§ãïŒã çŸåšã®ã¯ã©ã¹ã®é¢æ°ããã³ã³ã³ã¹ãã©ã¯ã¿ãŒã®ã³ãŒããçæããå Žåããã£ãŒã«ãã®èª¬æã®é åã䜿çšãããŸããããã«ã€ããŠã¯äžèšã§èª¬æããŸããã
- LocalObjectDef-çŸåšã®é¢æ°ãŸãã¯ã³ã³ã¹ãã©ã¯ã¿ãŒã®æ¬äœå ã®ãã¹ãŠã®ããŒã«ã«å€æ°ãèšè¿°ããããã«äœ¿çšãããŸãïŒCoolã§ã¯ãããŒã«ã«å€æ°ã¯letã¹ããŒãã¡ã³ãã䜿çšããŠå®£èšãããŸãïŒã
- ValueObjectDef-å€ã«ãã£ãŠéä¿¡ãããããŒã¿ãä¿åããããã®äžçš®ã®ããŒã«ã«å€æ°ã Coolã§ã¯ããã®ãããªã¯ã©ã¹ã¯IntãStringãBoolã§ãã
- ArgObjectDefã¯ãçŸåšã®é¢æ°ã®åŒæ°ã§ãã åŒæ°ã®çªå·ãååãããã³ã¿ã€ããå«ãŸããŸãã
ãæ°ã¥ããããããŸããããCoolã§ã¯ããã¹ãŠã®çµæã¯è¡šçŸã§ãã ãŸããåã³ã³ã¹ãã©ã¯ã¿ãŒãšåé¢æ°å ã«ã¯ã exprã 1ã€ã ããããŸãã ãããã³ãŒããžã§ãã¬ãŒã¿ãŒã®äž»èŠãªãã€ã³ãã§ããããã®æ§é ãåŠçããããã«EmitExpressionïŒITree expressionNodeïŒé¢æ°ãå°å ¥ãããŸããã ã³ãŒãã¯æ¬¡ã®ãšããã§ãïŒäžéšã®éšåãããŒã¯ä»ãã®æ¥åã«çœ®ãæããŠçç¥ããŸããïŒã
ObjectDef result; switch (expressionNode.Type) { case CoolGrammarLexer.ASSIGN: result = EmitAssignOperation(expressionNode); break; // ... case CoolGrammarLexer.EQUAL: result = EmitEqualOperation(expressionNode); break; case CoolGrammarLexer.PLUS: case CoolGrammarLexer.MINUS: case CoolGrammarLexer.MULT: case CoolGrammarLexer.DIV: result = EmitArithmeticOperation(expressionNode); break; //... case CoolGrammarLexer.Term: if (expressionNode.ChildCount == 1) result = EmitExpression(expressionNode.GetChild(0)); else result = EmitExplicitInvoke(expressionNode); break; case CoolGrammarLexer.ImplicitInvoke: result = EmitInplicitInvoke(expressionNode); break; case CoolGrammarLexer.IF: result = EmitIfBranch(expressionNode); break; case CoolGrammarLexer.Exprs: for (int i = 0; i < expressionNode.ChildCount - 1; i++) { var objectDef = EmitExpression(expressionNode.GetChild(i)); objectDef.Remove(); } result = EmitExpression(expressionNode.GetChild(expressionNode.ChildCount - 1)); break; //... case CoolGrammarLexer.INTEGER: result = EmitInteger(expressionNode); break; } return result;
ã芧ã®ãšãããããªãŒããŒãïŒexpressionNodeïŒã®ã¿ã€ãã«å¿ããŠããã®æŒç®åã®åœä»€ãçæããé·ãã±ãŒã¹ããé¢æ°ãåŒã³åºãããŸãã
çæãããé¢æ°ã§çµæãè¿ãã«ã¯ãåŒã³ãŒãã®çæåŸã«åçŽãªOpCodes.Retåœä»€ã䜿çšããŸãïŒé¢æ°ãMainãªã©ã®äœãè¿ããªãå Žåãã¹ã¿ãã¯ããªãŒããŒãããŒããªãããã«ãRetã®åã«OpCodes.Popãè¿œå ããŸãïŒã
ãšã³ããªãã€ã³ãã決å®ããã«ã¯ã AssemblyBuilderã§å®çŸ©ãããŠããSetEntryPointã¡ãœããïŒMethodInfo entryMethodïŒ ã䜿çšãããŸãã ãŸãã STAThreadAttributeå±æ§ã¯ãã¢ããªã±ãŒã·ã§ã³ãåäžã®ã¹ã¬ããã§å®è¡ãããŠããããšã瀺ããšã³ããªãã€ã³ãã¡ãœããã«èšå®ããå¿ èŠããããŸãã é¢æ°ãšãšã³ããªãã€ã³ããå®çŸ©ããã³ãŒãã¯ãDefineFunctionã«ãããŸãã
質å ïŒãããã®ãããªæ§é ã®ã³ãŒããçæããæ¹æ³ïŒ
mathïŒæ°åŠâæ°ããæ°åŠã ïŒäœããã®åŒã®ãã£ãŒã«ããå²ãåœãŠããããã§ã¯æ°ããæ°åŠïŒã
åç ïŒãŸãæåã«ãCïŒã³ã³ãã€ã©ãŒããããã£ãŠã³ã³ãã€ã©ãŒããã®å Žã§èšç®ãçæããªãããšãç解ããå¿ èŠããããŸã-ããã¯äžå¯èœã§ãã ã€ãŸã å³åŽã®åŒã¯ããã©ã«ãã®ã³ã³ã¹ãã©ã¯ã¿ãŒã§è©äŸ¡ããããšèšãããã§ãã
ãããŠãåŒã³ãŒãïŒããã§ã¯æ°ããæ°åŠïŒãçæãããåŸãåœä»€OpCodes.StfldãŸãã¯OpCodes.Stsfldã ãããããééçãã£ãŒã«ãããã³éçãã£ãŒã«ãã®ãã®ã³ã³ã¹ãã©ã¯ã¿ãŒã®æ¬äœã«è¿œå ãããŸãã
ããã€ãã®CILåœä»€ãšèšèšã®èª¬æ
CILã¯ã¹ã¿ãã¯èšèªã§ããã€ãŸãããã¹ãŠã®æäœã¯ã¹ã¿ãã¯ã䜿çšããŠå®è¡ãããŸãã ããšãã°ãMathã¯ã©ã¹ãããã£ããããæ°ãèšç®ããé¢æ°åŒã³åºãã¯ã次ã®ããã«ãšã³ã³ãŒããããŸãã
ldsfld class Math Main::math ldsfld int32 Main::i callvirt instance int32 Math::fibonacci(int32) stloc.0
ããã§ã¯ãæåã«æ°åŠã€ã³ã¹ã¿ã³ã¹ãã³ãã«ãã¹ã¿ãã¯ã«ããŒãããã次ã«æž¡ãããintåã®åŒæ°ãããŒããããŸãã ãã®åŸã OpCodes.callvirtåœä»€ã䜿çšããŠfibonaccié¢æ°ãåŒã³åºãããŸãïŒã¯ã©ã¹ã®å éšé¢æ°ãåŒã³åºããšãã«éåžžã®OpCodes.callåœä»€ã䜿çšããããããã¯ã©ã¹èšè¿°åãæž¡ãå¿ èŠã¯ãããŸããïŒã æåŸã®stloc.0ã¹ããŒãã¡ã³ãã¯ãæ»ãå€ãããŒã«ã«å€æ°ã®çªå·0ã«æ ŒçŽããŸãã
ããŠãäžèšã«åŸã£ãŠãé¢æ°ã®æåã®åŒæ°ã¯ãæ瀺çãªåœ¢åŒã®åŒæ°ããªããŠããåŒã³åºãããã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ïŒthisïŒãžã®ãã€ã³ã¿ãŒã§ããããšã«æ³šæããŠãã ããã
CILã®ãã詳现ãªèª¬æã¯ãããšãã°ã Wikipediaã«ãããŸãã
ããããReflection.Emitã䜿çšããŠããã€ãã®æ§ææ§é ãã³ãŒãã£ã³ã°ããæ¹æ³ã説æããæ¹ãè¯ãã§ãããã
ç®è¡æŒç®ãšæ¯èŒæŒç®
ãããã®æäœã¯åçŽã«ãšã³ã³ãŒããããŸã-æåã«ã¹ã¿ãã¯ã«ããã·ã¥ãããŸã
ãªãã©ã³ãã次ã«ãªãã¬ãŒã·ã§ã³ã³ãŒãïŒç®è¡æŒç®ã®å Žåããããã¯OpCodes.AddãOpCodes.SubãOpCodes.MulãOpCodes.Divã§ãããæ¯èŒæŒç®ã®å Žåã OpCodes.CeqãOpCodes.CltãOpCodes.Cgtã§ãã
CILã«ã¯ãã以äžããŸãã¯ã以äžãã®æ¯èŒã®ããã®åœä»€ããªãããããã®ãããªæ¯èŒãçæããããã«ã1ã€ã§ã¯ãªã3ã€ã®åœä»€ã䜿çšãããŸãïŒããã§ãã<=ãã¯ãnot>ããšåçã§ãïŒã
OpCodes.Cgt OpCodes.Ldc_I4_0 OpCodes.Ceq
OpCodes.Ceqã¯ãã¹ã¿ãã¯äžã®2ã€ã®èŠçŽ ãæ¯èŒããçããå Žåã¯1ãè¿ããçãããªãå Žåã¯0ãè¿ããŸãã
æ§ç¯ããå Žå
ç®è¡æŒç®ã®ã³ãŒãã£ã³ã°ãšæ¯èŒãããšããã®åœä»€ã®ã³ãŒãã£ã³ã°ã«ã¯å°é£ããããŸããããã¯ãæ¡ä»¶ä»ããžã£ã³ããšç¡æ¡ä»¶ãžã£ã³ãã®ã©ãã«ã«äœããã®æ¹æ³ã§ã©ãã«ãä»ããå¿ èŠããããšããäºå®ã«ãããŸãã ãã ããããã¯ç°¡åã«è¡ããŸãã DefineLabelã¡ãœããã䜿çšããŠãILGeneratorã§ã©ãã«ãäœæããŸãããã®åŸãLabelã¡ãœããã䜿çšããŠãMarkLabelã¡ãœããã䜿çšããŠã³ãŒããããŒã¯ããå¿ èŠããããŸãã ãããã®ã©ãã«ã¯ãæ¡ä»¶ä»ãããã³ç¡æ¡ä»¶ã®åå²åœä»€ããšã³ã³ãŒãããããã«äœ¿çšãããŸãã ãããã£ãŠã OpCodes.Brfalseã¯ãã¹ã¿ãã¯ã®æäžéšã®å€ããŒãã«çãããšãã«çºçããæ¡ä»¶ä»ãé·ç§»ã§ãã OpCodes.Brã¯ç¡æ¡ä»¶ã®ç§»è¡ã§ãã æ確ã«ããããã«ãã³ãŒãã瀺ããŸããã
protected ObjectDef EmitIfBranch(ITree expressionNode) { var checkObjectDef = EmitExpression(expressionNode.GetChild(0)); checkObjectDef.Load(); checkObjectDef.Remove(); var exitLabel = CurrentILGenerator_.DefineLabel(); var elseLabel = CurrentILGenerator_.DefineLabel(); CurrentILGenerator_.Emit(OpCodes.Brfalse, elseLabel); var ifObjectDef = EmitExpression(expressionNode.GetChild(1)); ifObjectDef.Load(); ifObjectDef.Remove(); CurrentILGenerator_.Emit(OpCodes.Br, exitLabel); CurrentILGenerator_.MarkLabel(elseLabel); var elseObjectDef = EmitExpression(expressionNode.GetChild(2)); elseObjectDef.Load(); elseObjectDef.Remove(); CurrentILGenerator_.MarkLabel(exitLabel); return LocalObjectDef.AllocateLocal(GetMostNearestAncestor(ifObjectDef.Type, elseObjectDef.Type)); }
æ§ç¯ããªãã
ãã®èšèšã¯Ifã«ãã䌌ãŠããŸãã ãã®ãã¶ã€ã³ã®æ¬äœã®äžã§ãåžžã«Popãå®è¡ããå¿ èŠãããããšãå¿ããªãã§ãã ããã å éšåŒãè©äŸ¡ããããã®çµæã¯äœ¿çšãããŸããã ïŒCoolã§ã¯ããã®ã¹ããŒãã¡ã³ãã¯åžžã«voidãè¿ããŸãïŒã
æŒç®åã@ãããã³ãCaseã
@æŒç®åã¯åºæ¬çã«CïŒã³ãŒãã®åŒïŒa as BïŒ.methodNameã«äžèŽããCaseã¹ããŒãã¡ã³ãã¯åçåãã§ãã¯ã䜿çšããåŒa is B in CïŒã«äžèŽããŸãã
æ®å¿µãªããããããã®æŒç®åã¯å®è£ ãããŠããŸããã
ãã ããç¹å®ã®åãžã®ãã£ã¹ãã¯castclass <class>ã¹ããŒãã¡ã³ãã䜿çšããŠå®è£ ãããŠãããšèšããŸã ïŒã¡ãœãããžã®ãã£ã¹ããšã¡ãœããã®åŒã³åºãã¯ã constrainedã䜿çšããŠããã«å®è£ ãããŸãã<thisType> [prefix] ïŒ
ãŸããåçãªåãã§ãã¯ã¯isinst <class>ã¹ããŒãã¡ã³ãã䜿çšããŠå®è£ ãããŸãã
ããŒã¯ã³IDåŠç
ããªãŒããŒãã¿ã€ããIdã¿ã€ãã«å¯Ÿå¿ããå Žåã次ã®ã¢ã¯ã·ã§ã³ãå®è¡ãããŸãïŒ EmitIdValueé¢æ°ã§ïŒã
- ããŒã«ã«å€æ°ã§ã®èå¥åæ€çŽ¢ïŒèŠã€ãããªãå ŽåïŒ
- é¢æ°ã®åŒæ°ã§èå¥åãæ€çŽ¢ããèŠã€ãããªãå Žåã¯ã
- çŸåšã®ã¯ã©ã¹ã®ãã£ãŒã«ãã§èå¥åãæ€çŽ¢ããèŠã€ãããªãå Žåã¯ã
- Idãå®çŸ©ãããŠããªããšã©ãŒãçæããŸã
ãã®ã»ã¯ã·ã§ã³ã§ã¯ãCILåœä»€ãšãè€éã§ãããšæãããæ§ææ§é ã®ã³ãŒãçæã«ã€ããŠèª¬æããŸããã ä»ã®ãã¹ãŠã®CILã®æé ã«ã€ããŠã¯ãWikiããŒãžãåç §ã§ããŸãããã®ããŒãžãžã®ãªã³ã¯ã¯ããããã¯ã®æåŸã«ãããŸãã ãŸãããœãŒã¹ã³ãŒãã§ã³ãŒãçæã®è©³çŽ°ã確èªã§ããŸãã
ãšã©ãŒåŠç
ã³ã³ãã€ã©ã®ãšã©ãŒã¯ç°ãªããŸãïŒ
ãšã©ãŒçªå·ãã³ãŒãå ã®äœçœ®ïŒè¡ãšåïŒããšã©ãŒã®çš®é¡ãããã³ãã®èª¬æãå«ãæœè±¡ã¯ã©ã¹CompilerErrorãããããã¹ãŠã«å¯ŸããŠäœæãããŸããã
åå¥ãšã©ãŒãšæ§æãšã©ãŒãå¶åŸ¡ããããšã¯äžå¯èœã§ãïŒå°ãªããšããã®ãããžã§ã¯ãã§ã¯ãã¬ã¯ãµãŒãšããŒãµãŒã®ã¬ãã«ã§ãšã©ãŒããå埩ããããšãANTLRã§åŠçããŸããã§ããïŒã ããã§ã¯ãäŸå€ãåçŽã«ãã£ããããã察å¿ãããšã©ãŒã€ã³ã¹ã¿ã³ã¹ãäœæãããŸãã ãããã¯ãã¹ãŠCoolCompier.csãã¡ã€ã«ã§ç¢ºèªã§ããŸãã
ãã ããã»ãã³ãã£ãã¯ãšã©ãŒã®ãã§ãã¯ïŒäž»ã«åãã§ãã¯ïŒã¯ããemitãã®ãã¹ãŠã®æ©èœã«å®è£ ãããŠããŸãã åãã§ãã¯ã¯ç°¡åãªæ¹æ³ã§å®è£ ãããŸãã ããã«ããããããããã®ã¢ãããŒãã«ããã1ã€ã®ãã¹ã§è€æ°ã®ã»ãã³ãã£ãã¯ãšã©ãŒã®èªèãå®çŸã§ããŸãã 以äžã«äŸã瀺ããŸãïŒç®è¡æŒç®ããšã©ãŒãæ€åºãããå Žåãæ§æããªãŒã¯åŒãç¶ãèµ°æ»ããŸãïŒ
protected ObjectDef EmitArithmeticOperation(ITree expressionNode) { var returnObject1 = EmitExpression(expressionNode.GetChild(0)); var returnObject2 = EmitExpression(expressionNode.GetChild(1)); if (returnObject1.Type != IntegerType || returnObject1.Type != returnObject2.Type) CompilerErrors.Add(new ArithmeticOperatorError( returnObject1.Type, returnObject2.Type, CompilerErrors.Count, expressionNode.Line, expressionNode.GetChild(1).CharPositionInLine, expressionNode.GetChild(0).CharPositionInLine)); ... }
ãŸããäžè¬çãªçš®é¡ã®ãšã©ãŒã«ã¯ãããã¡ã€ã«ãå¥ã®ããã»ã¹ã§ããžãŒã§ãããããšã³ããªãã€ã³ããèŠã€ãããŸããã§ããããªã©ã®ãšã©ãŒããããŸãããããã«ã€ããŠè©±ãã®ã¯ç¹ã«é¢çœããããŸããã
ã€ã³ã¿ãŒãã§ãŒã¹
æ§æã®åŒ·èª¿è¡šç€º
ç§ãèšã£ãããã«ãã³ãŒããæäœããããã®ã³ã³ããŒãã³ããšããŠãWPFã§AvalonEditã䜿çšããŸãã ã
æ§æã匷調ããããã«ãæ¡åŒµå.xshdãæã€ç¹å¥ãªãã¡ã€ã«ã䜿çšãããŸããããã¯ãããŸããŸãªåèªãèŠåã®ãã©ã³ãã¹ã¿ã€ã«ãèšè¿°ããŠããŸãã
ããšãã°ãã³ã¡ã³ãã¯æ¬¡ã®ããã«ç€ºãããŸãã
<Span color="Comment" begin="--" /> <Span color="Comment" multiline="true" begin="\(\*" end="\*\)" />
ãã®ãããªããŒã¯ãŒãïŒ
<Color name="Keywords" foreground="Blue" /> ... <Keywords color="Keywords"> <Word>classWord> <Word>elseWord> <Word>falseWord> ... Keywords>
ãŸããã©ã®æåã·ãŒã±ã³ã¹ãæ°åãŸãã¯æååã§ããããããã³ãããã匷調衚瀺ããæ¹æ³ã決å®ããããã«å¿ èŠãªã«ãŒã«ããããŸãã
<Rule foreground="DarkBlue"> \b0[xX][0-9a-fA-F]+ # hex number |\b ( \d+(\.[0-9]+)? #number with optional floating point | \.[0-9]+ #or just starting with floating point ) ([eE][+-]?[0-9]+)? # optional exponent Rule>
ä»ã®ãã¹ãŠã®åŒ·èª¿è¡šç€ºã«ãŒã«ã¯ããã¡ã€ã«CoolHighlighting.xshdã«ãããŸãã
æãããã¿ãšèªåè£å®
ãã®ãšãã£ã¿ãŒã§ã¯ãããã¯ã®æãããã¿ãšå±éãå¯èœã§ã CoolFoldingStrategy.csã«å®è£ ãããŠããŸã ã ã³ãŒãã¯ç§ã®ãã®ã§ã¯ãªãã®ã§ãã³ã¡ã³ãããããšã¯æ§ããŸãã 圌ã®ãããã§ãäžæ¬åŒ§ã®éã«ãããã¹ãŠã®ãã®ãæå°åãŸãã¯æ¡åŒµã§ãããšããèšããŸããã ã«ãŒãã«ã¯ãã®ãããªæ©äŒã¯ãªãã¯ããªã®ã§ãããã¯ããŸãæ£ãããªãããã§ãã
ãŸãããã®ã³ã³ããŒãã³ãã䜿çšãããšèªåè£å®ãå®è¡ã§ããŸãããã³ãŒãçæã«é¢ä¿ãªãã»ãã³ãã£ãã¯ããªãŒãçæã§ããå¥ã®ã¢ãŒããã¯ãã£ãæåããå®è¡ããå¿ èŠããã£ããããå®è¡ããŸããã§ããã
æåŸã«ãã€ã³ã¿ãŒãã§ã€ã¹ã®èŠ³ç¹ãããèŠã€ãã£ããšã©ãŒãã³ãŒãè¡ã«é¢é£ä»ããæ¹æ³ã«ã€ããŠèª¬æããŸãã 以äžã«ç€ºãã³ãŒãã§ã¯ããã£ãªããžãã¹ã¯ããŒã«ãããç¹å®ã®ãšã©ãŒãçºçããå Žæã«ãã£ãªããžã転éãããŸãã
tbEditor.ScrollTo((int)compilerError.Line, (int)compilerError.ColumnStart); int offset = tbEditor.Document.GetOffset((int)compilerError.Line, (int)compilerError.ColumnStart); tbEditor.Select(offset, 0); tbEditor.Focus();
tbEditor-ãšãã£ã¿ãŒã³ã³ããŒãã³ãã®ã€ã³ã¹ã¿ã³ã¹ã
compilerError-ãšã©ãŒïŒèª¬æã¯åã®ã»ã¯ã·ã§ã³ã«ãããŸãïŒ;
ãããŠãã¡ããããã®ã»ã¯ã·ã§ã³ã¯ãã³ã³ãã€ã©èªäœã®ã¹ã¯ãªãŒã³ãªãã§ã¯å®å šã§ã¯ãããŸããã
![](http://habrastorage.org/storage2/226/a04/b80/226a04b8030a10388d078957c6af08cd.png)
ã³ãŒããšãã£ã¿ã¯å·Šäžã«ããããã°ãšãšã©ãŒã®ãªã¹ãã¯å·Šäžã«ãããŸãã å³åŽã«ã¯ãã³ãŒããã³ã³ãã€ã«ããããã®ãã¿ã³ããããŸãïŒF5ãæŒããŠã³ã³ãã€ã«ããŠå®è¡ããããšããF6ãæŒããŠã³ã³ãã€ã«ããããšãã§ããŸãïŒã
æ確ã«ããããã«ãããã°ã©ã ã¯ããŒã¯ã³ã®ãªã¹ããšæ§æããªãŒïŒå³åŽïŒã衚瀺ããŸãã ããŒã¯ã³ãŸãã¯æ§ææ§é ãããã«ã¯ãªãã¯ãããšããã£ãªããžãã¹ã¯ããŒã«ããããã£ãªããžãé©åãªå Žæã«ç§»åããŸãã
ãããªãã¢ãŒããã¯ãã£ã®æ¹å
çŸåšã®ç¥èãšååãªã¢ãããŒã·ã§ã³ã§åã³Coolèšèªã®ã³ã³ãã€ã©ãæžãå§ããå Žåããããã2ã€ã®ã³ã³ãã€ã«æ®µé-ã»ãã³ãã£ãã¯ããªãŒã®æ§ç¯ãš3ãŸãã¯4ã¢ãã¬ã¹ã®äžéã³ãŒãã®çæ-ãéžæããã§ãããã
ã»ãã³ãã£ãã¯ããªãŒã¯ãæ¢ã«è¿°ã¹ãããã«ãã³ãŒãçæã®åã«ãªã¢ã«ã¿ã€ã ã§ã»ãã³ãã£ãã¯ãšã©ãŒã®èªå眮æãšãã§ãã¯ãå®çŸããŸãã
3ã¢ãã¬ã¹ã®äžéã³ãŒãã䜿çšãããšãçŸåšã®ã¢ãããŒãã§ã¯é©çšã§ããªãæé©åææ³ãé©çšã§ããŸãã ããšãã°ããã®çš®ã®ã³ãã³ãã®ç³ã¿èŸŒã¿ãšä»ã®æé©åïŒ
stloc.0
ldloc.0
ãœãŒã¹ã®èª¬æïŒããŒãã¹ïŒ
2011幎ã«MSTUã§éå¬ããããDesigning Compilersãã³ãŒã¹ã§æã£ãŠãããã¹ãŠã®ã©ããã
ãã¹ãŠã®å®éšå®€ã®èª¬æïŒ
- ã¿ã¹ã¯1.ææ³ãåå²ããŸãã ãã®ã©ãã§ã¯ãææ³åå²ã¢ã«ãŽãªãºã ãå®è£
ããŠããŸã ã æé ã®è©³çŽ°ãªèª¬æãšé åºã¯ã102ããŒãžã®ç¬¬2å·»ã®æç§æžãAho A.ãUlman J.解æã翻蚳ãããã³ã³ã³ãã€ã«ã®çè«ãã«ãããŸãã ïŒææ³ã®æåã
åœæã¯ãŸã LINQã§éãã§ããããšãèŠããŠããŸãã ãããã£ãŠããããã®é¢æ°ã®ã³ãŒãã¯ãå¹ççã§çŸãããšã¯ã»ã©é ããã®ã®ãããªãçãããšãå€æããŸããã :)
- ã¿ã¹ã¯2.éåžžã®èšèªã®ãã§ãŒã³ã®èªèã ããã§ã¯ã次ã®ãµãã¿ã¹ã¯ãå®è£
ãããŠããŸãã
- éåžžã®ä¿æ°ã䜿çšããæšæºã·ã¹ãã ã®ãœãªã¥ãŒã·ã§ã³ã
説æ ïŒæ£èŠè¡šçŸã¯å·ŠåŽã®ææ³ããäœæããå¿ èŠããããŸãã ã€ãŸã éåžžã®ä¿æ°ïŒSRSïŒã䜿çšããŠã·ã¹ãã ãã解決ãããŸãã ä¿æ°ã¯çµç«¯ã§ãããæªç¥æ°ã¯éçµç«¯ã§ãã
ããšãã°ããã®ãããªææ³ã®å ŽåïŒ
Σ = {0, 1}
N = {S, A, B}
P = {S â 0âA|1âS|λ, A â 0âB|1âA, B â 0âS|1âB}
S = S
次ã®åŒãå€æããŸãïŒå°ããªãšã©ãŒããããŸããããã€ã³ãã¯ãããŸããïŒã
S = 1*+1*â0â1*â0â1*â0â1*+1*â0â1*â0â(0â1*â0â1*â0)*â0â1*
A = 1*â0â1*â0â1*+1*â0â(0â1*â0â1*â0)*â0â1*
B = 1*â0â1*+(0â1*â0â1*â0)*â0â1*
ãã®ã©ãã§äœæ¥ããŠãããšãã代æ°ã+ããã*ããã/ãã®éåžžã®æäœããæ£èŠè¡šçŸã®ã³ã³ããã¹ãã§å¯Ÿå¿ãããorãããconcatenationãããiterationãã®æäœã«ãªãŒããŒããŒãããããšã§ãSRKã¡ãœããã解ãããšãã§ããããšã«æ°ä»ããŸããã¬ãŠã¹ãéåžžã®SLAEã解決ãããšããïŒ å¯äžã®ããšã¯ãæé©åã®ããã«äœããå€æŽãããããšã§ãã
ãã ãããããã®æäœããªãŒããŒããŒãããããšãéèŠãªã¿ã¹ã¯ã§ãããããã¯æ°åã§ã¯ãããŸããããããã®è¡ãšã«ãŒã«ã¯ç°ãªãããã§ãïŒé£çµããå Žåãè¡ããæ¥çãããå¿ èŠãããããorãæäœã§ã¯åã圢åŒã®ãŸãŸã«ããå¿ èŠãããããŒãã¯ç©ºã®ã»ããã§ãïŒÃïŒåäœã¯ã©ã ãïŒÎ»ïŒã§ãã ãããã£ãŠã0ãŸãã¯1ã«ããä¹ç®ãŸãã¯å ç®ã®å Žåããããã®è¡ãæé©åããå¿ èŠããããŸããæé©åããªããšãããã«ãèšåŒµãããŸãã
- æ£èŠä¿æ°ã䜿çšããæšæºã®é£ç«æ¹çšåŒã®è§£ã§ããæ£èŠè¡šçŸã䜿çšããŠãNFAïŒé決å®æ§æéãªãŒãããã³ïŒãæ§ç¯ããŸãã
- NCAãã·ãã¥ã¬ãŒãããããšã決å®ããŸããã èŠããã«-ããã¯ä¿®æ£ãããæ·±ãæ€çŽ¢ã§ã
- éåžžã®ä¿æ°ã䜿çšããæšæºã·ã¹ãã ã®ãœãªã¥ãŒã·ã§ã³ã
- åé¡3. Coca-Yanger-Kasamiã¢ã«ãŽãªãºã
ããã§ã¯ãKok-Yanger-Kasamiã¢ã«ãŽãªãºã ã䜿çšããŠè§£æãå®è£ ããå¿ èŠããããŸãã
ãã®ã¢ã«ãŽãªãºã ã§ã¯ãææ³ãChomskyã®æšæºåœ¢åŒã§æå®ããå¿ èŠããããŸãããããã¯ãã¡ããäžäŸ¿ã§ããåå¥è§£æåšã®æ¬ åŠãäžäŸ¿ããåŒãèµ·ããã®ã§ãããŒãµãŒãããããèªèããããã«ããã¹ãŠã®ããŒã¯ã³ã¯ã¹ããŒã¹ã§åºåãããªããã°ãªããŸããã
ãã®å®ç¿ã©ãã®çµæã¯ã解æããŒãã«ãšãå ¥åãããæååãç¹å®ã®ææ³ã«å±ãããã©ããã®å®éã®å®çŸ©ã§ãã
- ã¿ã¹ã¯4.ååž°éäžã®æ¹æ³
ããã§ã¯ãååž°éäžã®æ¹æ³ãå®è£ ããå¿ èŠããããŸãããåãååã«ã€ããŠããã¹ãŠã®LLïŒ*ïŒã³ãŒããžã§ãã¬ãŒã¿ãŒïŒããšãã°ãANTLRïŒã¯ã³ãŒããçæããŸããããã§ã®ã¿ããã¹ãŠãæåã§å®è£ ãããŸããæ確ã«ããããã«ã解æããªãŒãããã«æ§ç¯ãããŸãã
- 5-8. Cool
----Cool .NET, .
, , Cool, , , :
- , ( .pdf):
- Evaluating Simple C Expressions â - .
- iFlop â iFlop .
äžéšã®ã©ãã§ã¯ãMicrosoft.GLEEã°ã©ãã®ã¬ã³ããªã³ã°ã«çŽ æŽãããããããééãããææã®ã©ã€ãã©ãªã䜿çšããŠããããšã«æ³šæããŠãã ããããã®èšäºããå€æãããšããã®ã©ã€ãã©ãªã§ã¯ããã€ãã®å·§åŠãªã¢ã«ãŽãªãºã ãšãã¥ãŒãªã¹ãã£ãã¯ã䜿çšãããã¬ã³ããªã³ã°ãããã°ã©ãã人ã«ãã£ãŠæãããããŒããµã€ãºãæ倧ã§æå°ã®é åãå æããŠããããã«èŠããŸãã ïŒããã§ã»ãšãã©èª°ãèšåããŠããªãã®ã¯å¥åŠã§ãïŒã
å©ç¹ã¯ããã®ã©ã€ãã©ãªã®äœ¿çšãç°¡åãªããšã§ããããšãã°ãããŒãéã®ãšããžã®è¿œå ã¯ããœãŒã¹ã1ã€ã®ããŒãã®ååã§ãã¿ãŒã²ãããå¥ã®ããŒãã®ååã§ããé¢æ°ã䜿çšããŠå®è¡ã
Edge AddEdge(string source, string target)
ããŸãã
ã€ãŸãããŒãéã«éä¿¡ãè¿œå ããããã«ãæåã«ããŒããäœæããå¿ èŠã¯ãããŸããã
é¢æ°ã䜿çš
Edge AddNode(string nodeId)
ãããšãEdgeãªããžã§ã¯ãã®ã€ã³ã¹ã¿ã³ã¹ãè¿ãããå±æ§ïŒããã¹ãã®è²ãããŒãã®è²ãã€ã³ãã³ããªã©ïŒãå€æŽ
ã§ããŸãããç§ã¯äœãèããŠããç§ã¯Microsoftã®ãµããŒã¿ãŒã§ã¯ãããŸããã ïŒ
ãã¹ãŠã®ã¹ããŒã ãäœæããã³ç·šéããã«ã¯ã䟿å©ãªãªã³ã©ã€ã³ãµãŒãã¹lucidchart.comã䜿çšããŸããã
æåŠ
ç§ã¯ãã®ãããã¯ã®èè ã«åæããŸãããã®ããŒãã«é¢ããå€ãã®æ¬ãèªãå¿ èŠã¯ãããŸãããã1åã§ååã§ããååã§ãã
ã³ã³ãã€ã©ããå§ãããŸããPrinciplesãTechnologies and Toolsã2008ãAlfred W. AhoãMonica S. LamãRavi SetiãJeffrey D. Ullmanã
ãŸããç§ããã䜿çšããCILæ瀺ã®ãªã¹ããžã®ãªã³ã¯ãæçš¿ããŸãã
GitHubãããžã§ã¯ã
ããã ãã§ãïŒ