예제 #1
0
 public static vMRClsDef.EnumInferenceType MapInferTypeFuntionDeftovMR(
     FunctionTypeDef.EnumInferenceType em_InferenceType)
 {
     switch(em_InferenceType)
     {
         case FunctionTypeDef.EnumInferenceType.PRIMARY:
             return vMRClsDef.EnumInferenceType.PRIMARY;
         case FunctionTypeDef.EnumInferenceType.NEEDSECONDTIME:
             return vMRClsDef.EnumInferenceType.NEEDSECONDTIME;
         case FunctionTypeDef.EnumInferenceType.SECONDTIME:
             return vMRClsDef.EnumInferenceType.SECONDTIME;
         default:
             return vMRClsDef.EnumInferenceType.PRIMARY;
     }
 }
예제 #2
0
        public void Emit(CompilationContext context)
        {
            context.EmitComment(";Function call");

            var expressionType = ((IHasType)Tokens[0]).GetExpressionType(context);

            if (!(expressionType.BaseType is FunctionTypeDef))
            {
                throw new Exception("Can't call expression type: " + expressionType + " as a function");
            }

            FunctionTypeDef functionType = (FunctionTypeDef)expressionType.BaseType;
            ExpressionType  returnType   = functionType.ReturnType;

            //List<ExpressionType> parameterTypes = functionType.ArgumentTypes;

            if (returnType.GetSize() > 4)
            {
                //Make space for return value in caller stack
                //context.EmitInstruction(new IRMoveImmediate() { To = "eax", Value = new ImmediateValue(function.ReturnType.GetSize()) });
                //context.EmitInstruction(new IRAdd() { Left = "sp", Right = "eax", To = "sp" });
                throw new LargeReturnValuesNotSupportedException();
            }

            //Push base pointer on stack
            context.EmitInstruction(new IRPushRegister()
            {
                From = "bp"
            });

            //Save registers (TODO: Not actually needed until we have smarter allocation that uses registers instead of stack)
            //context.EmitInstruction(new IRPushRegister() { From = "eax" });
            //context.EmitInstruction(new IRPushRegister() { From = "ebx" });
            //context.EmitInstruction(new IRPushRegister() { From = "ecx" });
            //context.EmitInstruction(new IRPushRegister() { From = "edx" });

            int argumentCount = Tokens.Count - 1;
            int argumentsSize = 0;

            if (argumentCount != functionType.ArgumentTypes.Count)
            {
                throw new ArgumentCountMismatchException(Tokens[0].ToString(), functionType.ArgumentTypes.Count, argumentCount);
            }

            if (Tokens.Count > 1)
            {
                //Push arguments on stack in reverse order
                for (int i = Tokens.Count - 1; i > 0; i--)
                {
                    var argExpressionType   = ((IHasType)Tokens[i]).GetExpressionType(context);
                    var paramExpressionType = functionType.ArgumentTypes[functionType.ArgumentTypes.Count - 1 - (Tokens.Count - 1 - i)];

                    TypeChecking.CheckExpressionTypesMatch(paramExpressionType, argExpressionType);

                    //Push argument value on stack
                    ((ICodeEmitter)Tokens[i]).Emit(context);

                    argumentCount++;
                    argumentsSize += argExpressionType.GetSize();
                }
            }

            var returnLabel = new LabelAddressValue(context.CreateNewLabel());

            //Address of function -> eax
            ((ICodeEmitter)Tokens[0]).Emit(context);
            context.EmitInstruction(new IRPop()
            {
                To = "eax"
            });

            //Set base pointer to be the top of current function's stack which will be the bottom
            //of the called function's stack
            context.EmitInstruction(new IRMoveRegister()
            {
                From = "sp", To = "bp"
            });

            //Push return address
            context.EmitInstruction(new IRPushImmediate()
            {
                Value = returnLabel
            });

            //Jump to function
            context.EmitInstruction(new IRJumpRegister()
            {
                Address = "eax"
            });

            //Resume here, reclaim space from arguments pushed on stack
            context.EmitLabel(returnLabel.Value);
            context.EmitInstruction(new IRMoveImmediate()
            {
                To = "ebx", Value = new ImmediateValue(argumentsSize)
            });
            context.EmitInstruction(new IRSub()
            {
                To = "sp", Left = "sp", Right = "ebx"
            });

            //Restore registers (TODO: Not actually needed until we have smarter allocation that uses registers instead of stack)
            //context.EmitInstruction(new IRPop() { To = "edx" });
            //context.EmitInstruction(new IRPop() { To = "ecx" });
            //context.EmitInstruction(new IRPop() { To = "ebx" });
            //context.EmitInstruction(new IRPop() { To = "eax" });

            //Reset base pointer
            context.EmitInstruction(new IRPop()
            {
                To = "bp"
            });

            if (returnType.GetSize() > 4)
            {
                //Return value is already on stack
                throw new LargeReturnValuesNotSupportedException();
            }
            else if (returnType.GetSize() > 0)
            {
                //Return value in eax, put on stack
                context.EmitInstruction(new IRPushRegister()
                {
                    From = "eax"
                });
            }
        }
예제 #3
0
 public static vMRClsDef.EnumInferenceResultType MapInferResultTypeFuntiontovMR(
     FunctionTypeDef.EnumInferenceResultType em_InferResultType)
 {
     switch(em_InferResultType)
     {
         case FunctionTypeDef.EnumInferenceResultType.DIAGNOSIS:
             return vMRClsDef.EnumInferenceResultType.DIAGNOSIS;
         case FunctionTypeDef.EnumInferenceResultType.THERAPY:
             return vMRClsDef.EnumInferenceResultType.THERAPY;
         case FunctionTypeDef.EnumInferenceResultType.SELFMONITOR:
             return vMRClsDef.EnumInferenceResultType.SELFMONITOR;
         case FunctionTypeDef.EnumInferenceResultType.MSEVALUATION:
             return vMRClsDef.EnumInferenceResultType.MSEVALUATION;
         case FunctionTypeDef.EnumInferenceResultType.RISKEVALUATION:
             return vMRClsDef.EnumInferenceResultType.RISKEVALUATION;
         case FunctionTypeDef.EnumInferenceResultType.ADVERSEEVENT:
             return vMRClsDef.EnumInferenceResultType.ADVERSEEVENT;
         case FunctionTypeDef.EnumInferenceResultType.DIETARY:
             return vMRClsDef.EnumInferenceResultType.DIETARY;
         case FunctionTypeDef.EnumInferenceResultType.PHYSICALACTIVITY:
             return vMRClsDef.EnumInferenceResultType.PHYSICALACTIVITY;
         case FunctionTypeDef.EnumInferenceResultType.OTHER:
             return vMRClsDef.EnumInferenceResultType.OTHER;
         default:
             return vMRClsDef.EnumInferenceResultType.OTHER;
     }
 }