using System; using System.Collections.Generic; using System.Linq; using System.Text; using Bridge; using Bridge.Linq; using Bridge.Html5; namespace WebMrbc { [IgnoreCast] public class ENodeInitializeBlock : Block { public const string type_name = "enode_initialize"; internal EObjectWorkspace workspace_; public ENodeInitializeBlock() : base(type_name) { } public void init() { this.appendDummyInput() .appendField("初期化処理"); this.appendStatementInput("DO") .setCheck(null); this.setColour(230); this.setTooltip(""); this.setHelpUrl(""); } internal void OnCreate(EObjectWorkspace workspace, Create cre) { workspace_ = workspace; } internal void OnChange(EObjectWorkspace workspace, Change chg) { } internal void OnDelete(EObjectWorkspace workspace, Delete del) { } internal void OnMove(EObjectWorkspace workspace, Move mov) { } } [IgnoreCast] public class EObjectInitializeBlock : Block { public const string type_name = "eobject_initialize"; internal EObjectWorkspace workspace_; public EObjectInitializeBlock() : base(type_name) { } public void init() { this.appendDummyInput() .appendField("初期化処理"); this.appendStatementInput("DO") .setCheck(null); this.setColour(230); this.setTooltip(""); this.setHelpUrl(""); } internal void OnCreate(EObjectWorkspace workspace, Create cre) { workspace_ = workspace; } internal void OnChange(EObjectWorkspace workspace, Change chg) { } internal void OnDelete(EObjectWorkspace workspace, Delete del) { } internal void OnMove(EObjectWorkspace workspace, Move mov) { } } public class EPropertyBlock : Block { internal JsonPropertyInfo PropertyInfo { get; private set; } internal EObjectWorkspace Workspace { get; private set; } public string Identifier { get; protected set; } public string Description { get; protected set; } public int PropertyCode { get; protected set; } public int PropertySize { get; protected set; } public EPropertyBlock(string type) : base(type) { } internal bool InitPropertyInfo(EObjectWorkspace workspace, bool initial = false) { var c = workspace.eobject; PropertyInfo = null; foreach (var pi in c.properties) { if (pi.propertyCode != PropertyCode) continue; if (!initial && !App.BaseObjectPropertyList.Contains(pi)) continue; PropertyInfo = pi; Identifier = CodeGenerator.GetPropertyIdentifier(pi); Description = pi.description; PropertySize = ((pi.arrayCount == 0) ? 1 : pi.arrayCount) * pi.size; break; } if (PropertyInfo == null) { dispose(true); return false; } return true; } internal void OnCreate(EObjectWorkspace workspace, Create cre) { Workspace = workspace; if (PropertyInfo == null) { if (!InitPropertyInfo(workspace, true)) return; } setFieldValue(PropertyCode.ToString("X2"), "PROPERTY_CODE"); setFieldValue(Identifier, "IDENTIFIER"); setFieldValue(Description, "DESCRIPTION"); setFieldValue(PropertySize.ToString(), "PROPERTY_SIZE"); } internal void OnChange(EObjectWorkspace workspace, Change chg) { } internal void OnDelete(EObjectWorkspace workspace, Delete del) { } internal void OnMove(EObjectWorkspace workspace, Move mov) { } } public class EPropertyFixLenBlock : EPropertyBlock { public const string type_name = "eproperty_fixlen"; internal Tuple[] cases_; internal int defaultCount_; internal bool userGetter_; public Connection statementConnection_; public Connection retvalConnection_; public EPropertyFixLenBlock() : base(type_name) { } public void init() { setHelpUrl("http://www.example.com/"); setColour(230); appendDummyInput("PROPERTY") .appendField("EPC:") .appendField("__", "PROPERTY_CODE") .appendField("__", "DESCRIPTION") .appendField("__", "IDENTIFIER") .appendField("Size:") .appendField("__", "PROPERTY_SIZE") .appendField("byte"); setMutator(new Mutator(new[] { EPropertyFixLenConstBlock.type_name, EPropertyFixLenRangeBlock.type_name, EPropertyFixLenDefaultBlock.type_name })); setTooltip(new Func(() => { if ((cases_.Length == 0) && (defaultCount_ == 0)) { return "条件に合うブロックを実行"; } else if ((cases_.Length == 0) && (defaultCount_ != 0)) { return "条件に合うブロックを実行、合うものがなければ最後のブロックを実行"; } else if ((cases_.Length != 0) && (defaultCount_ == 0)) { return "条件に合うブロックを実行"; } else if ((cases_.Length != 0) && (defaultCount_ != 0)) { return "条件に合うブロックを実行、合うものがなければ最後のブロックを実行"; } return ""; })); cases_ = new Tuple[0]; defaultCount_ = 0; userGetter_ = true; updateSetter_(); updateGetter_(userGetter_); } /// /// Create XML to represent the number of else-if and else inputs. /// /// XML storage element. public Element mutationToDom(bool opt_caseIds) { if ((cases_.Length == 0) && (defaultCount_ == 0)) { return null; } var container = Document.CreateElement("mutation"); for (var i = 0; i < cases_.Length; i++) { var caseInfo = Document.CreateElement("case"); caseInfo.AppendChild(Document.CreateTextNode(cases_[i].Item1)); if (cases_[i].Item3 == null) caseInfo.SetAttribute("value", cases_[i].Item2); else { caseInfo.SetAttribute("minimum", cases_[i].Item2); caseInfo.SetAttribute("maximum", cases_[i].Item3); } container.AppendChild(caseInfo); } container.SetAttribute("default", defaultCount_.ToString()); container.SetAttribute("user_getter", userGetter_ ? "1" : "0"); container.SetAttribute("property_code", PropertyCode.ToString("X2")); container.SetAttribute("identifier", Identifier); container.SetAttribute("description", Description); container.SetAttribute("property_size", PropertySize.ToString()); return container; } /// /// Parse XML to restore the else-if and else inputs. /// /// XML storage element. public void domToMutation(Element xmlElement) { cases_ = new Tuple[0]; Element childNode; for (var i = 0; (childNode = (dynamic)xmlElement.ChildNodes[i]) != null; i++) { if (childNode.NodeName.ToLower() == "case") { var description = (childNode.ChildNodes.Length != 0) ? childNode.ChildNodes[0].NodeValue : ""; var value = childNode.GetAttribute("value"); if (value != null) cases_.Push(new Tuple(description, value, null)); else { var min = childNode.GetAttribute("minimum"); var max = childNode.GetAttribute("maximum"); if ((min != null) && (max != null)) cases_.Push(new Tuple(description, min, max)); } } } var count = xmlElement.GetAttribute("default"); defaultCount_ = count == null ? 0 : Script.ParseInt(count, 10); count = xmlElement.GetAttribute("user_getter"); userGetter_ = count == null ? false : (Script.ParseInt(count, 10) != 0); count = xmlElement.GetAttribute("property_code"); PropertyCode = Script.ParseInt(count, 16); if (Workspace != null) InitPropertyInfo(Workspace, true); Identifier = xmlElement.GetAttribute("identifier"); Description = xmlElement.GetAttribute("description"); count = xmlElement.GetAttribute("property_size"); PropertySize = count == null ? 0 : Script.ParseInt(count, 10); updateSetter_(); updateGetter_(userGetter_); } /// /// Populate the mutator's dialog with this block's components. /// /// Mutator's workspace. /// Root block in mutator. public Block decompose(Workspace workspace) { var containerBlock = workspace.newBlock(EPropertyFixLenContainerBlock.type_name); containerBlock.initSvg(); var connection = containerBlock.getInput("STACK").connection; for (var i = 0; i < cases_.Length; i++) { Block caseBlock; var description = getFieldValue("CASE_DESCRIPTION" + i); var value = getFieldValue("CASE_VALUE" + i); if (value != null) { caseBlock = workspace.newBlock(EPropertyFixLenConstBlock.type_name); caseBlock.setFieldValue(description, "DESCRIPTION"); caseBlock.setFieldValue(value, "CONST"); } else { var min = getFieldValue("CASE_MIN" + i); var max = getFieldValue("CASE_MAX" + i); if ((min != null) && (max != null)) { caseBlock = workspace.newBlock(EPropertyFixLenRangeBlock.type_name); caseBlock.setFieldValue(description, "DESCRIPTION"); caseBlock.setFieldValue(min, "RANGE_MIN"); caseBlock.setFieldValue(max, "RANGE_MAX"); } else continue; } caseBlock.initSvg(); connection.connect(caseBlock.previousConnection); connection = caseBlock.nextConnection; } if (defaultCount_ != 0) { var defaultBlock = workspace.newBlock(EPropertyFixLenDefaultBlock.type_name); defaultBlock.initSvg(); connection.connect(defaultBlock.previousConnection); } containerBlock.setFieldValue(this.userGetter_ ? "TRUE" : "FALSE", "USER_GETTER"); return containerBlock; } /// /// Reconfigure this block based on the mutator dialog's components. /// /// Root block in mutator. public void compose(Block containerBlock) { var clauseBlock = containerBlock.getInputTargetBlock("STACK"); // Count number of inputs. cases_ = new Tuple[0]; defaultCount_ = 0; var statementConnections = new Connection[0]; Connection defaultStatementConnection = null; while (clauseBlock != null) { switch (clauseBlock.type) { case EPropertyFixLenConstBlock.type_name: { var description = clauseBlock.getFieldValue("DESCRIPTION"); var value = clauseBlock.getFieldValue("CONST"); cases_.Push(new Tuple(description, value, null)); statementConnections.Push(((EPropertyFixLenConstBlock)clauseBlock).statementConnection_); } break; case EPropertyFixLenRangeBlock.type_name: { var description = clauseBlock.getFieldValue("DESCRIPTION"); var range_min = clauseBlock.getFieldValue("RANGE_MIN"); var range_max = clauseBlock.getFieldValue("RANGE_MAX"); cases_.Push(new Tuple(description, range_min, range_max)); statementConnections.Push(((EPropertyFixLenRangeBlock)clauseBlock).statementConnection_); } break; case EPropertyFixLenDefaultBlock.type_name: { defaultCount_++; defaultStatementConnection = ((EPropertyFixLenDefaultBlock)clauseBlock).statementConnection_; } break; default: throw new Exception("Unknown block type."); } clauseBlock = (clauseBlock.nextConnection != null) ? clauseBlock.nextConnection.targetBlock() : null; } updateSetter_(); // Reconnect any child blocks. for (var i = 0; i <= cases_.Length; i++) { Mutator.reconnect(statementConnections[i], this, "SET" + i); } Mutator.reconnect(defaultStatementConnection, this, "DEFAULT_SET"); var userGetter_ = containerBlock.getFieldValue("USER_GETTER"); if (userGetter_ != null) { var userGetter = userGetter_ == "TRUE"; if (this.userGetter_ != userGetter) { if (userGetter) { updateGetter_(true); // Restore the stack, if one was saved. Mutator.reconnect(this.statementConnection_, this, "GET"); this.statementConnection_ = null; Mutator.reconnect(this.retvalConnection_, this, "GET_RET"); this.retvalConnection_ = null; } else { // Save the stack, then disconnect it. var getterConnection = this.getInput("GET").connection; this.statementConnection_ = getterConnection.targetConnection; var getretConnection = this.getInput("GET_RET").connection; this.retvalConnection_ = getretConnection.targetConnection; if (this.statementConnection_ != null) { var doBlock = getterConnection.targetBlock(); doBlock.unplug(); doBlock.bumpNeighbours_(); } if (this.retvalConnection_ != null) { var doBlock = getretConnection.targetBlock(); doBlock.unplug(); doBlock.bumpNeighbours_(); } updateGetter_(false); } } } } /// /// Store pointers to any connected child blocks. /// /// Root block in mutator. public void saveConnections(Block containerBlock) { var clauseBlock = containerBlock.getInputTargetBlock("STACK"); var i = 0; while (clauseBlock != null) { switch (clauseBlock.type) { case EPropertyFixLenConstBlock.type_name: { var inputSet = getInput("SET" + i); ((EPropertyFixLenConstBlock)clauseBlock).statementConnection_ = (inputSet != null) ? inputSet.connection.targetConnection : null; i++; } break; case EPropertyFixLenRangeBlock.type_name: { var inputSet = getInput("SET" + i); ((EPropertyFixLenRangeBlock)clauseBlock).statementConnection_ = (inputSet != null) ? inputSet.connection.targetConnection : null; i++; } break; case EPropertyFixLenDefaultBlock.type_name: { var inputDo = getInput("DEFAULT_SET"); ((EPropertyFixLenDefaultBlock)clauseBlock).statementConnection_ = (inputDo != null) ? inputDo.connection.targetConnection : null; } break; default: throw new Exception("Unknown block type."); } clauseBlock = (clauseBlock.nextConnection != null) ? clauseBlock.nextConnection.targetBlock() : null; } var inputGet = getInput("GET"); statementConnection_ = (inputGet != null) ? inputGet.connection.targetConnection : null; var inputGetRet = getInput("GET_RET"); retvalConnection_ = (inputGetRet != null) ? inputGetRet.connection.targetConnection : null; } /// /// Modify this block to have the correct number of inputs. /// private void updateSetter_() { // Delete everything. if (getInput("DEFAULT") != null) { removeInput("DEFAULT"); removeInput("DEFAULT_SET"); } var i = 0; while (getInput("CASE" + i) != null) { removeInput("CASE" + i); removeInput("SET" + i); i++; } // Rebuild block. var getLabel = this.getInput("GET_LABEL"); i = 0; foreach (var c in cases_) { if (c.Item3 == null) { appendDummyInput("CASE" + i) .appendField("設定値が") .appendField(c.Item1, "CASE_DESCRIPTION" + i) .appendField(c.Item2, "CASE_VALUE" + i) .appendField("の"); } else { appendDummyInput("CASE" + i) .appendField("設定値が") .appendField(c.Item1, "CASE_DESCRIPTION" + i) .appendField(c.Item2, "CASE_MIN" + i) .appendField("から") .appendField(c.Item3, "CASE_MAX" + i) .appendField("の"); } if (getLabel != null) { this.moveInputBefore("CASE" + i, "GET_LABEL"); } appendStatementInput("SET" + i) .appendField("とき"); if (getLabel != null) { this.moveInputBefore("SET" + i, "GET_LABEL"); } i++; } if (defaultCount_ != 0) { if (cases_.Length == 0) { appendDummyInput("DEFAULT") .appendField("値が設定される"); } else { appendDummyInput("DEFAULT") .appendField("設定値が不明の"); } if (getLabel != null) { this.moveInputBefore("DEFAULT", "GET_LABEL"); } appendStatementInput("DEFAULT_SET") .appendField("とき"); if (getLabel != null) { this.moveInputBefore("DEFAULT_SET", "GET_LABEL"); } } } private void updateGetter_(bool userGetter) { userGetter_ = userGetter; if (getInput("GET") != null) { removeInput("GET_LABEL"); removeInput("GET"); removeInput("GET_RET"); } // Rebuild block. if (userGetter_) { appendDummyInput("GET_LABEL") .appendField("値が取得される"); appendStatementInput("GET") .appendField("とき"); appendValueInput("GET_RET") .setCheck("String") .setAlign(Blockly.ALIGN_RIGHT) .appendField("返す値は"); } } } public class EPropertyFixLenContainerBlock : Block { public const string type_name = "eproperty_fixlen_container"; public EPropertyFixLenContainerBlock() : base(type_name) { } public void init() { appendDummyInput() .appendField("条件"); appendStatementInput("STACK"); // TODO:実行時に変更できない・・・(Dropdownでも×) appendDummyInput("USER_GETTER_INPUT") .appendField("取得時に保存してあるプロパティ値を返す。") .appendField(new FieldCheckbox("TRUE"), "USER_GETTER"); setColour(230); setTooltip(""); contextMenu = false; } } [IgnoreCast] public class EPropertyFixLenConstBlock : Block { public const string type_name = "eproperty_fixlen_const"; public Connection statementConnection_; public EPropertyFixLenConstBlock() : base(type_name) { } public void init() { setColour(230); appendDummyInput() .appendField(new FieldTextInput("定数"), "DESCRIPTION") .appendField(new FieldNumber("0", "-Infinity", "Infinity", 1), "CONST"); setPreviousStatement(true); setNextStatement(true); setTooltip("プロパティ値"); contextMenu = false; } } public class EPropertyFixLenRangeBlock : Block { public const string type_name = "eproperty_fixlen_range"; public Connection statementConnection_; public EPropertyFixLenRangeBlock() : base(type_name) { } public void init() { setColour(230); appendDummyInput() .appendField(new FieldTextInput("範囲"), "DESCRIPTION") .appendField(new FieldNumber("0", "-Infinity", "Infinity", 1), "RANGE_MIN") .appendField("から") .appendField(new FieldNumber("255", "-Infinity", "Infinity", 1), "RANGE_MAX"); setPreviousStatement(true); setNextStatement(true); setTooltip("プロパティ値"); contextMenu = false; } } public class EPropertyFixLenDefaultBlock : Block { public const string type_name = "eproperty_fixlen_default"; public Connection statementConnection_; public EPropertyFixLenDefaultBlock() : base(type_name) { } public void init() { setColour(230); appendDummyInput() .appendField("その他"); setPreviousStatement(true); setTooltip("不明なプロパティ値"); contextMenu = false; } } public class EPropertyVarLenBlock : EPropertyBlock { public const string type_name = "eproperty_varlen"; public EPropertyVarLenBlock() : base(type_name) { } public void init() { this.appendDummyInput("PROPERTY") .appendField("EPC:") .appendField("__", "PROPERTY_CODE") .appendField("__", "DESCRIPTION") .appendField("__", "IDENTIFIER") .appendField("Size:") .appendField("__", "PROPERTY_SIZE") .appendField("byte"); this.appendStatementInput("SET") .setCheck("EPropertySetHandler") .appendField("設定"); this.appendValueInput("SET_RET") .setCheck("Number") .setAlign(Blockly.ALIGN_RIGHT) .appendField("設定に使用したバイト数"); this.appendStatementInput("GET") .setCheck("EPropertyGetHandler") .appendField("取得"); this.appendValueInput("GET_RET") .setCheck("String") .setAlign(Blockly.ALIGN_RIGHT) .appendField("返すデータ"); this.setColour(230); this.setTooltip(""); this.setHelpUrl("http://www.example.com/"); getField("PROPERTY_CODE").EDITABLE = true; } } partial class Ruby { internal string defineENode(JsonNodeInfo enode, Workspace workspace) { var identifier = enode.identifier; var nodes = new node[0]; var super = new colon2_node(this, new const_node(this, intern("ECNL")), intern("ENode")); global = false; var lv = local_switch(); { var body = new begin_node(this, workspaceToNodes(workspace)); var cls = new class_node(this, intern(identifier), super, body); nodes.Push(cls); } local_resume(lv); global = true; return finish(nodes); } internal string defineEObject(JsonObjectInfo eobject, Workspace workspace) { var identifier = eobject.identifier; var nodes = new node[0]; var super = new colon2_node(this, new const_node(this, intern("ECNL")), intern("EObject")); global = false; var lv = local_switch(); { var body = new begin_node(this, workspaceToNodes(workspace)); var cls = new class_node(this, intern(identifier), super, body); nodes.Push(cls); } local_resume(lv); global = true; return finish(nodes); } public node enode_initialize(ENodeInitializeBlock block) { var workspace = block.workspace_; var enode = workspace.eobject; var properties = workspace.allEProperties(workspace.Workspace); def_node def; var lv = local_switch(); { var fparams = new arg_node[] { new arg_node(this, local_add_f("eojx3")) }; var statements_do = statementToCode(block, "DO"); { var eprpinib_table = new lvar_node(this, intern("eprpinib_table")); var propinis = new node[0]; foreach (var pi in enode.properties) { if (CodeGenerator.IsExtractProperty(pi)) continue; var pb = properties.FirstOrDefault((i) => { return i.PropertyCode == pi.propertyCode; }); var ecnl_eproperty = new colon2_node(this, new const_node(this, intern("ECNL")), intern("EProperty")); var args = new node[] { new int_node(this, pi.propertyCode, 16), getAccess(pi, pb), getSize(pi, pb), getExinf(pi, pb), getSetter(pb), getGetter(pb) }; var propini = new call_node(this, ecnl_eproperty, intern("new"), args); propinis.Push(propini); } var asgn = new asgn_node(this, eprpinib_table, new array_node(this, propinis, true)); statements_do.progs.Push(asgn); } { var args = new node[] { new lvar_node(this, intern("eojx3")), new lvar_node(this, intern("eprpinib_table")) }; var super = new super_node(this, args); statements_do.progs.Push(super); } def = new def_node(this, intern("initialize"), fparams, statements_do); } local_resume(lv); return def; } public node eobject_initialize(EObjectInitializeBlock block) { var workspace = block.workspace_; var eobject = workspace.eobject; var properties = workspace.allEProperties(workspace.Workspace); def_node def; var lv = local_switch(); { var fparams = new arg_node[] { new arg_node(this, local_add_f("eojx3")), new arg_node(this, local_add_f("enod")) }; var statements_do = statementToCode(block, "DO"); { var eprpinib_table = new lvar_node(this, intern("eprpinib_table")); var propinis = new node[0]; foreach (var pi in eobject.properties) { if (CodeGenerator.IsExtractProperty(pi)) continue; var pb = properties.FirstOrDefault((i) => { return i.PropertyCode == pi.propertyCode; }); var ecnl_eproperty = new colon2_node(this, new const_node(this, intern("ECNL")), intern("EProperty")); var args = new node[] { new int_node(this, pi.propertyCode, 16), getAccess(pi, pb), getSize(pi, pb), getExinf(pi, pb), getSetter(pb), getGetter(pb) }; var propini = new call_node(this, ecnl_eproperty, intern("new"), args); propinis.Push(propini); } var asgn = new asgn_node(this, eprpinib_table, new array_node(this, propinis, true)); statements_do.progs.Push(asgn); } { var args = new node[] { new int_node(this, eobject.type.classGroup.classGroupCode, 16), new int_node(this, eobject.type.classCode, 16), new lvar_node(this, intern("eojx3")), new lvar_node(this, intern("enod")), new lvar_node(this, intern("eprpinib_table")) }; var super = new super_node(this, args); statements_do.progs.Push(super); } def = new def_node(this, intern("initialize"), fparams, statements_do); } local_resume(lv); return def; } private node getSize(JsonPropertyInfo pi, EPropertyBlock pb) { if (pb != null) pi = pb.PropertyInfo; return new int_node(this, ((pi.arrayCount == 0) ? 1 : pi.arrayCount) * pi.size, 10); } private node getAccess(JsonPropertyInfo pi, EPropertyBlock pb) { if (pb != null) pi = pb.PropertyInfo; var list = new node[0]; if (pi.access.Contains("RULE_ANNO")) list.Push(new colon2_node(this, new const_node(this, intern("ECNL")), intern("EPC_RULE_ANNO"))); if (pi.access.Contains("RULE_SET")) list.Push(new colon2_node(this, new const_node(this, intern("ECNL")), intern("EPC_RULE_SET"))); if (pi.access.Contains("RULE_GET")) list.Push(new colon2_node(this, new const_node(this, intern("ECNL")), intern("EPC_RULE_GET"))); if (pi.access.Contains("ANNOUNCE")) list.Push(new colon2_node(this, new const_node(this, intern("ECNL")), intern("EPC_ANNOUNCE"))); if (pi.access.Contains("VARIABLE")) list.Push(new colon2_node(this, new const_node(this, intern("ECNL")), intern("EPC_VARIABLE"))); switch (list.Length) { case 0: return new colon2_node(this, new const_node(this, intern("ECNL")), intern("EPC_NONE")); case 1: return list[0]; } var or = intern("|"); call_node result = new call_node(this, list[0], or, list[1]); for (int i = 2; i < list.Length; i++) { result = new call_node(this, result, or, list[i]); } return result; } private node getExinf(JsonPropertyInfo pi, EPropertyBlock pb) { switch (pi.propertyCode) { // 現在時刻設定 case 0x97: // 現在年月日設定 case 0x98: return new nil_node(this); // その他 default: if (pb == null) return new sym_node(this, get_var_name(CodeGenerator.GetPropertyIdentifier(pi))); return new sym_node(this, get_var_name(pb.Identifier)); } } private node getSetter(EPropertyBlock pb) { if (pb == null) return new sym_node(this, intern("ecn_data_prop_set")); return new sym_node(this, intern(pb.Identifier + "_set")); } private node getGetter(EPropertyBlock pb) { if (pb == null) return new sym_node(this, intern("ecn_data_prop_get")); return new sym_node(this, intern(pb.Identifier + "_get")); } public node eproperty_fixlen(EPropertyFixLenBlock block) { var text_identifier = block.Identifier; var value_description = block.Description; var value_property_code = block.PropertyCode.ToString("X2"); var value_property_size = block.PropertySize.ToString(); // 設定関数定義 def_node def_set; var lv = local_switch(); { var prop = local_add_f("prop"); var src = local_add_f("src"); var args = new arg_node[0]; args.Push(new arg_node(this, prop)); args.Push(new arg_node(this, src)); var statements_set = new begin_node(this, new node[0]); { var src_bytesize = new call_node(this, new lvar_node(this, src), intern("bytesize")); var size = new int_node(this, Script.ParseInt(value_property_size)); var size_check_cond = new call_node(this, src_bytesize, intern("!="), size); var size_check = new if_node(this, size_check_cond, new return_node(this, new int_node(this, 0)), null, false); statements_set.progs.Push(size_check); } { var anno_check_cond = new call_node(this, new lvar_node(this, prop), intern("anno")); var prop_exinf = new call_node(this, new lvar_node(this, prop), intern("exinf")); var set_anno_arg = new call_node(this, prop_exinf, intern("!="), new lvar_node(this, src)); var anno_check_then = new call_node(this, new lvar_node(this, prop), intern("set_anno"), new node[] { set_anno_arg }); var anno_check = new if_node(this, anno_check_cond, anno_check_then, null, false); statements_set.progs.Push(anno_check); } var val = local_add_f("val"); { node code; var lsrc = new lvar_node(this, src); var pos = new int_node(this, 0); switch (value_property_size) { case "1": code = new call_node(this, lsrc, intern("getbyte"), new node[] { pos }); break; case "2": code = new fcall_node(this, intern("ecnl_getshort"), new node[] { lsrc, pos }); break; case "4": code = new fcall_node(this, intern("ecnl_getint"), new node[] { lsrc, pos }); break; default: code = new int_node(this, -1); break; } code = new asgn_node(this, new lvar_node(this, val), code); statements_set.progs.Push(code); } if (block.cases_.Length > 0) { node argument0 = new lvar_node(this, val); if (argument0 == null) argument0 = new int_node(this, -1); var branches = new case_node.when_t[0]; for (var i = 0; i < block.cases_.Length; i++) { var branch = statementToCode(block, "SET" + i); var argument1 = block.getFieldValue("CASE_VALUE" + i); if (argument1 != null) { var when = new case_node.when_t() { body = branch }; when.value.Push(new int_node(this, argument1 == null ? 0 : Script.ParseInt(argument1, 10))); branches.Push(when); } else { var min = block.getFieldValue("CASE_MIN" + i); var max = block.getFieldValue("CASE_MAX" + i); if ((min != null) && (max != null)) { var when = new case_node.when_t() { body = branch }; when.value.Push(new dot2_node(this, new int_node(this, min == null ? 0 : Script.ParseInt(min, 10)), new int_node(this, max == null ? 0 : Script.ParseInt(max, 10)))); branches.Push(when); } } } { var branch = statementToCode(block, "DEFAULT_SET"); if (branch.progs.Length == 0) { branch = new begin_node(this, new node[] { new return_node(this, new int_node(this, 0)) }); } var when = new case_node.when_t() { body = branch }; branches.Push(when); } var code = new case_node(this, new lvar_node(this, val), branches); statements_set.progs.Push(code); } var value_set_ret = new return_node(this, new int_node(this, Script.ParseInt(value_property_size))); statements_set.progs.Push(value_set_ret); def_set = new def_node(this, intern(text_identifier + "_set"), args, statements_set); } local_resume(lv); // 取得関数定義 def_node def_get; lv = local_switch(); { var prop = local_add_f("prop"); var src = local_add_f("src"); var args = new arg_node[0]; args.Push(new arg_node(this, prop)); args.Push(new arg_node(this, src)); var statements_get = statementToCode(block, "GET"); var value_get_ret = valueToCode(block, "GET_RET"); if (value_get_ret == null) { value_get_ret = new return_node(this, new str_node(this, "")); } statements_get.progs.Push(value_get_ret); def_get = new def_node(this, intern(text_identifier + "_get"), args, statements_get); } local_resume(lv); // 設定関数定義と取得関数定義のリスト return node.cons(this, def_set, node.cons(this, def_get, null)); } public node eproperty_varlen(EPropertyVarLenBlock block) { var text_identifier = block.getFieldValue("IDENTIFIER"); var value_description = block.getFieldValue("DESCRIPTION"); var value_property_code = block.getFieldValue("PROPERTY_CODE"); var value_property_size = block.getFieldValue("PROPERTY_SIZE"); // 設定関数定義 def_node def_set; var lv = local_switch(); { var prop = local_add_f("prop"); var src = local_add_f("src"); var args = new arg_node[0]; args.Push(new arg_node(this, prop)); args.Push(new arg_node(this, src)); var statements_set = statementToCode(block, "SET"); var value_set_ret = valueToCode(block, "SET_RET"); if (value_set_ret == null) { value_set_ret = new return_node(this, new int_node(this, 0)); } statements_set.progs.Push(value_set_ret); def_set = new def_node(this, intern(text_identifier + "_set"), args, statements_set); } local_resume(lv); // 取得関数定義 def_node def_get; lv = local_switch(); { var prop = local_add_f("prop"); var src = local_add_f("src"); var args = new arg_node[0]; args.Push(new arg_node(this, prop)); args.Push(new arg_node(this, src)); var statements_get = statementToCode(block, "GET"); var value_get_ret = valueToCode(block, "GET_RET"); if (value_get_ret == null) { value_get_ret = new return_node(this, new str_node(this, "")); } statements_get.progs.Push(value_get_ret); def_get = new def_node(this, intern(text_identifier + "_get"), args, statements_get); } local_resume(lv); // 設定関数定義と取得関数定義のリスト return node.cons(this, def_set, node.cons(this, def_get, null)); } } }