//解析操作符 private bool P_Operator(Stack <TempOperator> operateStack, Stack <CodeObject> objectStack) { TempOperator curr = TempOperator.GetOper(PeekToken().Type); if (curr == null) { return(false); } ReadToken(); while (operateStack.Count > 0) { TempOperator oper = operateStack.Peek(); if (oper.Level >= curr.Level) { operateStack.Pop(); CodeOperator binexp = new CodeOperator(objectStack.Pop(), objectStack.Pop(), oper.Operator); objectStack.Push(binexp); } else { break; } } operateStack.Push(curr); return(true); }
ScriptObject ParseOperate(CodeOperator operate) { TokenType type = operate.Operator; ScriptObject left = ResolveOperand(operate.Left); switch (type) { case TokenType.Plus: ScriptObject right = ResolveOperand(operate.Right); if (left is ScriptString || right is ScriptString) { return(new ScriptString(m_script, left.ToString() + right.ToString())); } return(left.Compute(type, right)); case TokenType.Minus: case TokenType.Multiply: case TokenType.Divide: case TokenType.Modulo: case TokenType.InclusiveOr: case TokenType.Combine: case TokenType.XOR: case TokenType.Shr: case TokenType.Shi: return(left.Compute(type, ResolveOperand(operate.Right))); case TokenType.And: if (!left.LogicOperation()) { return(m_script.False); } return(m_script.CreateBool(ResolveOperand(operate.Right).LogicOperation())); case TokenType.Or: if (left.LogicOperation()) { return(m_script.True); } return(m_script.CreateBool(ResolveOperand(operate.Right).LogicOperation())); case TokenType.Equal: return(m_script.CreateBool(left.Equals(ResolveOperand(operate.Right)))); case TokenType.NotEqual: return(m_script.CreateBool(!left.Equals(ResolveOperand(operate.Right)))); case TokenType.Greater: case TokenType.GreaterOrEqual: case TokenType.Less: case TokenType.LessOrEqual: return(m_script.CreateBool(left.Compare(type, ResolveOperand(operate.Right)))); default: throw new ExecutionException(m_script, "不支持的运算符 " + type); } }
private ScriptObject ParseOperate(CodeOperator operate) { Scorpio.Compiler.TokenType @operator = operate.Operator; ScriptObject obj2 = this.ResolveOperand(operate.Left); switch (@operator) { case Scorpio.Compiler.TokenType.Plus: { ScriptObject obj3 = this.ResolveOperand(operate.Right); if ((obj2 is ScriptString) || (obj3 is ScriptString)) { return(new ScriptString(this.m_script, obj2.ToString() + obj3.ToString())); } return(obj2.Compute(@operator, obj3)); } case Scorpio.Compiler.TokenType.Minus: case Scorpio.Compiler.TokenType.Multiply: case Scorpio.Compiler.TokenType.Divide: case Scorpio.Compiler.TokenType.Modulo: case Scorpio.Compiler.TokenType.InclusiveOr: case Scorpio.Compiler.TokenType.Combine: case Scorpio.Compiler.TokenType.XOR: case Scorpio.Compiler.TokenType.Shi: case Scorpio.Compiler.TokenType.Shr: return(obj2.Compute(@operator, this.ResolveOperand(operate.Right))); case Scorpio.Compiler.TokenType.Or: if (!obj2.LogicOperation()) { return(this.m_script.CreateBool(this.ResolveOperand(operate.Right).LogicOperation())); } return(this.m_script.True); case Scorpio.Compiler.TokenType.And: if (obj2.LogicOperation()) { return(this.m_script.CreateBool(this.ResolveOperand(operate.Right).LogicOperation())); } return(this.m_script.False); case Scorpio.Compiler.TokenType.Equal: return(this.m_script.CreateBool(obj2.Equals(this.ResolveOperand(operate.Right)))); case Scorpio.Compiler.TokenType.NotEqual: return(this.m_script.CreateBool(!obj2.Equals(this.ResolveOperand(operate.Right)))); case Scorpio.Compiler.TokenType.Greater: case Scorpio.Compiler.TokenType.GreaterOrEqual: case Scorpio.Compiler.TokenType.Less: case Scorpio.Compiler.TokenType.LessOrEqual: return(this.m_script.CreateBool(obj2.Compare(@operator, this.ResolveOperand(operate.Right)))); } throw new ExecutionException(this.m_script, "不支持的运算符 " + @operator); }
//获取一个Object private CodeObject GetObject() { Stack <TempOperator> operateStack = new Stack <TempOperator>(); Stack <CodeObject> objectStack = new Stack <CodeObject>(); while (true) { objectStack.Push(GetOneObject()); if (!P_Operator(operateStack, objectStack)) { break; } } while (true) { if (operateStack.Count <= 0) { break; } TempOperator oper = operateStack.Pop(); CodeOperator binexp = new CodeOperator(objectStack.Pop(), objectStack.Pop(), oper.Operator); objectStack.Push(binexp); } CodeObject ret = objectStack.Pop(); if (ret is CodeMember) { CodeMember member = ret as CodeMember; if (member.Calc == CALC.NONE) { Token token = ReadToken(); switch (token.Type) { case TokenType.Assign: case TokenType.AssignPlus: case TokenType.AssignMinus: case TokenType.AssignMultiply: case TokenType.AssignDivide: case TokenType.AssignModulo: case TokenType.AssignCombine: case TokenType.AssignInclusiveOr: case TokenType.AssignXOR: case TokenType.AssignShr: case TokenType.AssignShi: return(new CodeAssign(member, GetObject(), token.Type, m_strBreviary, token.SourceLine)); default: UndoToken(); break; } } } return(ret); }
ScriptObject ParseOperate(CodeOperator operate) { TokenType type = operate.Operator; ScriptObject left = ResolveOperand(operate.Left); if (type == TokenType.Plus) { ScriptObject right = ResolveOperand(operate.Right); if (left is ScriptString || right is ScriptString) { return(m_script.CreateString(left.ToString() + right.ToString())); } return(left.Compute(type, right)); } else if (type == TokenType.And) { if (left.LogicOperation() == false) { return(m_script.False); } return(m_script.GetBoolean(ResolveOperand(operate.Right).LogicOperation())); } else if (type == TokenType.Or) { if (left.LogicOperation() == true) { return(m_script.True); } return(m_script.GetBoolean(ResolveOperand(operate.Right).LogicOperation())); } else if (type == TokenType.Equal) { return(m_script.GetBoolean(left.Equals(ResolveOperand(operate.Right)))); } else if (type == TokenType.NotEqual) { return(m_script.GetBoolean(!left.Equals(ResolveOperand(operate.Right)))); } else if (type == TokenType.Greater || type == TokenType.GreaterOrEqual || type == TokenType.Less || type == TokenType.LessOrEqual) { return(m_script.GetBoolean(left.Compare(type, ResolveOperand(operate.Right)))); } else { return(left.Compute(type, ResolveOperand(operate.Right))); } }
private void GenerateOperatorCode(CodeOperator opdDecl) { foreach (CodeComment commentDecl in opdDecl.Comments) { GenerateCommentCode(commentDecl); } WriteCustomAttributes(opdDecl.CustomAttributes); WriteAttributes(opdDecl.Attributes); Output.Write(GetClrTypeName(opdDecl.RetVal.Type)); Output.Write(" operator "); Output.Write(opdDecl.Name); Output.Write("("); var args = new List <string>(opdDecl.Parameters.Count); foreach (CodeMethodParameter param in opdDecl.Parameters) { string modifier = string.Empty; if (param.Direction == CodeMethodParameterDirection.Ref) { modifier = "ref "; } else if (param.Direction == CodeMethodParameterDirection.Out) { modifier = "out "; } args.Add(string.Format("{0}{1} {2}", modifier, param.Type, param.Name)); } Output.Write(string.Join(", ", args)); Output.Write(")"); WriteBlockStart(CodeGenBlockType.Method); GenerateMethodBodyCode(opdDecl.Body); WriteBlockEnd(CodeGenBlockType.Method); }
public override bool Compare(TokenType type, CodeOperator oper, ScriptNumber num) { ScriptNumberDouble val = num as ScriptNumberDouble; if (val == null) { throw new ExecutionException("数字比较 两边的数字类型不一致 请先转换再比较 "); } switch (type) { case TokenType.Greater: return(m_Value > val.m_Value); case TokenType.GreaterOrEqual: return(m_Value >= val.m_Value); case TokenType.Less: return(m_Value < val.m_Value); case TokenType.LessOrEqual: return(m_Value <= val.m_Value); } return(false); }
ScriptObject ParseOperate(CodeOperator operate) { TokenType type = operate.Operator; ScriptObject left = ResolveOperand(operate.Left); if (type == TokenType.Plus) { ScriptObject right = ResolveOperand(operate.Right); if (left is ScriptString || right is ScriptString) { return(m_script.CreateString(left.ToString() + right.ToString())); } else if (left is ScriptNumber && right is ScriptNumber) { return((left as ScriptNumber).Compute(TokenType.Plus, right as ScriptNumber)); } else { throw new ExecutionException("operate [+] left right is not same type"); } } else if (type == TokenType.Minus || type == TokenType.Multiply || type == TokenType.Divide || type == TokenType.Modulo || type == TokenType.InclusiveOr || type == TokenType.Combine || type == TokenType.XOR || type == TokenType.Shr || type == TokenType.Shi) { ScriptNumber leftNumber = left as ScriptNumber; if (leftNumber == null) { throw new ExecutionException("运算符[左边]必须是number类型"); } ScriptNumber rightNumber = ResolveOperand(operate.Right) as ScriptNumber; if (rightNumber == null) { throw new ExecutionException("运算符[右边]必须是number类型"); } return(leftNumber.Compute(type, rightNumber)); } else { if (left is ScriptBoolean) { bool b1 = ((ScriptBoolean)left).Value; if (type == TokenType.And) { if (b1 == false) { return(ScriptBoolean.False); } ScriptBoolean right = ResolveOperand(operate.Right) as ScriptBoolean; if (right == null) { throw new ExecutionException("operate [&&] right is not a bool"); } return(right.Value ? ScriptBoolean.True : ScriptBoolean.False); } else if (type == TokenType.Or) { if (b1 == true) { return(ScriptBoolean.True); } ScriptBoolean right = ResolveOperand(operate.Right) as ScriptBoolean; if (right == null) { throw new ExecutionException("operate [||] right is not a bool"); } return(right.Value ? ScriptBoolean.True : ScriptBoolean.False); } else { ScriptBoolean right = ResolveOperand(operate.Right) as ScriptBoolean; if (right == null) { throw new ExecutionException("operate [==] [!=] right is not a bool"); } bool b2 = right.Value; if (type == TokenType.Equal) { return(b1 == b2 ? ScriptBoolean.True : ScriptBoolean.False); } else if (type == TokenType.NotEqual) { return(b1 != b2 ? ScriptBoolean.True : ScriptBoolean.False); } else { throw new ExecutionException("nonsupport operate [" + type + "] with bool"); } } } else { ScriptObject right = ResolveOperand(operate.Right); if (left is ScriptNull || right is ScriptNull) { bool ret = false; if (type == TokenType.Equal) { ret = (left == right); } else if (type == TokenType.NotEqual) { ret = (left != right); } else { throw new ExecutionException("nonsupport operate [" + type + "] with null"); } return(ret ? ScriptBoolean.True : ScriptBoolean.False); } if (type == TokenType.Equal) { return(left.ObjectValue.Equals(right.ObjectValue) ? ScriptBoolean.True : ScriptBoolean.False); } else if (type == TokenType.NotEqual) { return(!left.ObjectValue.Equals(right.ObjectValue) ? ScriptBoolean.True : ScriptBoolean.False); } if (left.Type != right.Type) { throw new ExecutionException("[operate] left right is not same type"); } if (left is ScriptString) { return(((ScriptString)left).Compare(type, (ScriptString)right) ? ScriptBoolean.True : ScriptBoolean.False); } else if (left is ScriptNumber) { return(((ScriptNumber)left).Compare(type, (ScriptNumber)right) ? ScriptBoolean.True : ScriptBoolean.False); } else { throw new ExecutionException("nonsupport operate [" + type + "] with " + left.Type); } } } throw new ExecutionException("错误的操作符号 " + operate.Operator); }
public abstract bool Compare(TokenType type, CodeOperator oper, ScriptNumber num);
private string GenerateScript(CodeLine code, ref List <string> exportableObjects) { StringBuilder sb = new StringBuilder(); switch (code.CodeActionType) { case CodeLineType.File: break; case CodeLineType.Reference: break; case CodeLineType.Namespace: break; case CodeLineType.Comment: sb.Append("// "); sb.Append(code.Target); sb.Append(Environment.NewLine); break; case CodeLineType.Class: case CodeLineType.FunctionDefinition: break; case CodeLineType.Constructor: CodeConstructor constructor = code as CodeConstructor; if (constructor.VariableType == "Human") { sb.Append("InitHc;"); sb.Append(Environment.NewLine); /* * hc_agressivity, hc_attr, hc_basic_skills, hc_class, hc_face_number, hc_gallery, hc_importance, hc_last_mission, hc_name, hc_sex, hc_skills */ //Nation nation, Class classType, Sex sex, string name if (constructor.ParameterValues.Length == 4) { sb.Append("uc_side = "); sb.Append(constructor.ParameterValues[0]); sb.Append(";"); sb.Append(Environment.NewLine); sb.Append("uc_nation = "); sb.Append(constructor.ParameterValues[1]); sb.Append(";"); sb.Append(Environment.NewLine); sb.Append("hc_class = "); sb.Append(constructor.ParameterValues[2]); sb.Append(";"); sb.Append(Environment.NewLine); sb.Append("hc_sex = "); sb.Append(constructor.ParameterValues[3]); sb.Append(";"); sb.Append(Environment.NewLine); } if (constructor.ParameterValues.Length == 5) { sb.Append("hc_name = "); sb.Append(constructor.ParameterValues[4]); sb.Append(";"); sb.Append(Environment.NewLine); } sb.Append(constructor.Target); sb.Append(" = CreateHuman;"); sb.Append(Environment.NewLine); /* * InitHc; * uc_side = nation_american; * hc_class = class_engineer; * hc_basic_skills = [2,0,0,0]; * Bob = CreateHuman; */ } exportableObjects.Add($"Export {constructor.Target};{Environment.NewLine}"); break; case CodeLineType.FunctionCall: CodeFunction function = code as CodeFunction; if (function.FunctionName == "Starting") { sb.Append(function.FunctionName); sb.Append(Environment.NewLine); sb.Append("Begin"); sb.Append(Environment.NewLine); } else { sb.Append(function.FunctionName); sb.Append('('); if (function.Target.Length > 0) { sb.Append(function.Target); if (function.ParameterValues.Length > 0) { sb.Append(", "); } } for (int i = 0; i < function.ParameterValues.Length; i++) { sb.Append(function.ParameterValues[i]); if (i < function.ParameterValues.Length - 1) { if (function.FunctionName == "Wait") { sb.Append("$ "); } else { sb.Append(", "); } } } sb.Append(");"); sb.Append(Environment.NewLine); } break; case CodeLineType.CodeOperator: CodeOperator action = code as CodeOperator; if (action.FunctionName == "Assignment") { if (action.VariableType == "Skills") { if (action.ParameterValues.Count() != 4) { throw new Exception("Skills does not have 4 parameters!"); } sb.Append("hc_basic_skills = ["); for (int i = 0; i < 4; i++) { sb.Append(action.ParameterValues[i]); if (i < 3) { sb.Append(", "); } } sb.Append("];"); sb.Append(Environment.NewLine); } } break; default: break; } for (int i = 0; i < code.Children.Count; i++) { // Ignore constructors that stand for objects defined in the editor if (!(code.CodeActionType == CodeLineType.Class && code.Children[i].CodeActionType == CodeLineType.Constructor)) { sb.Append(GenerateScript(code.Children[i], ref exportableObjects)); } } return(sb.ToString()); }
ScriptObject ParseOperate(CodeOperator operate) { TokenType type = operate.Operator; ScriptObject left = ResolveOperand(operate.Left); if (type == TokenType.Plus) { ScriptObject right = ResolveOperand(operate.Right); if (left is ScriptString || right is ScriptString) { return(m_script.CreateString(left.ToString() + right.ToString())); } else if (left is ScriptNumber && right is ScriptNumber) { return((left as ScriptNumber).ComputePlus(right as ScriptNumber)); } else { throw new ExecutionException("operate [+] left right is not same type"); } } else if (type == TokenType.Minus || type == TokenType.Multiply || type == TokenType.Divide || type == TokenType.Modulo) { ScriptNumber leftNumber = left as ScriptNumber; if (leftNumber == null) { throw new ExecutionException("operate [+ - * /] left is not number"); } ScriptNumber rightNumber = ResolveOperand(operate.Right) as ScriptNumber; if (rightNumber == null) { throw new ExecutionException("operate [+ - * /] right is not number"); } if (operate.Operator == TokenType.Minus) { return(leftNumber.ComputeMinus(rightNumber)); } else if (operate.Operator == TokenType.Multiply) { return(leftNumber.ComputeMultiply(rightNumber)); } else if (operate.Operator == TokenType.Divide) { return(leftNumber.ComputeDivide(rightNumber)); } else if (operate.Operator == TokenType.Modulo) { return(leftNumber.ComputeModulo(rightNumber)); } } else { if (left is ScriptBoolean) { if (type == TokenType.And) { bool b1 = ((ScriptBoolean)left).Value; if (b1 == false) { return(ScriptBoolean.False); } ScriptBoolean right = ResolveOperand(operate.Right) as ScriptBoolean; if (right == null) { throw new ExecutionException("operate [&&] right is not a bool"); } return(right.Value ? ScriptBoolean.True : ScriptBoolean.False); } else if (type == TokenType.Or) { bool b1 = ((ScriptBoolean)left).Value; if (b1 == true) { return(ScriptBoolean.True); } ScriptBoolean right = ResolveOperand(operate.Right) as ScriptBoolean; if (right == null) { throw new ExecutionException("operate [||] right is not a bool"); } return(right.Value ? ScriptBoolean.True : ScriptBoolean.False); } else { bool b1 = ((ScriptBoolean)left).Value; ScriptBoolean right = ResolveOperand(operate.Right) as ScriptBoolean; if (right == null) { throw new ExecutionException("operate [==] [!=] right is not a bool"); } bool b2 = right.Value; if (type == TokenType.Equal) { return(b1 == b2 ? ScriptBoolean.True : ScriptBoolean.False); } else if (type == TokenType.NotEqual) { return(b1 != b2 ? ScriptBoolean.True : ScriptBoolean.False); } else { throw new ExecutionException("nonsupport operate [" + type + "] with bool"); } } } else { ScriptObject right = ResolveOperand(operate.Right); if (left is ScriptNull || right is ScriptNull) { bool ret = false; if (type == TokenType.Equal) { ret = (left == right); } else if (type == TokenType.NotEqual) { ret = (left != right); } else { throw new ExecutionException("nonsupport operate [" + type + "] with null"); } return(ret ? ScriptBoolean.True : ScriptBoolean.False); } if (type == TokenType.Equal) { return(left.ObjectValue.Equals(right.ObjectValue) ? ScriptBoolean.True : ScriptBoolean.False); } else if (type == TokenType.NotEqual) { return(!left.ObjectValue.Equals(right.ObjectValue) ? ScriptBoolean.True : ScriptBoolean.False); } if (left.Type != right.Type) { throw new ExecutionException("[operate] left right is not same type"); } if (left is ScriptString) { string str1 = ((ScriptString)left).Value; string str2 = ((ScriptString)right).Value; bool ret = false; if (type == TokenType.Greater) { ret = string.Compare(str1, str2) < 0; } else if (type == TokenType.GreaterOrEqual) { ret = string.Compare(str1, str2) <= 0; } else if (type == TokenType.Less) { ret = string.Compare(str1, str2) > 0; } else if (type == TokenType.LessOrEqual) { ret = string.Compare(str1, str2) >= 0; } else { throw new ExecutionException("nonsupport operate [" + type + "] with string"); } return(ret ? ScriptBoolean.True : ScriptBoolean.False); } else if (left is ScriptNumber) { return(((ScriptNumber)left).Compare(type, operate, (ScriptNumber)right) ? ScriptBoolean.True : ScriptBoolean.False); } else { throw new ExecutionException("nonsupport operate [" + type + "] with " + left.Type); } } } throw new ExecutionException("错误的操作符号 " + operate.Operator); }