public void Push(MelonObject value) { if (value == null) { throw new MelonException($"Invalid value 'null' was pushed to the stack!"); } _stack.Push(value); }
public MelonType GetTypeFromValue(MelonObject value) { if (value is MelonInstance melonInstance) { return(melonInstance.Type); } else if (value is MelonType melonType) { return(melonType); } else { return(anyType); } }
private int GetTypeReference(MelonObject obj) { if (obj is MelonInstance melonInstance) { return(_engine.Types.KeyByValue(melonInstance.Type)); } else if (obj is MelonType melonType) { return(_engine.Types.KeyByValue(melonType)); } else { return(_engine.Types.KeyByValue(_engine.anyType)); } }
public Variable AddVariable(string name, MelonObject value, TypeReference type) { //if (value is MelonInstance melonInstance) { // type = melonInstance.Type; //} //else if (value is MelonType melonType) { // type = melonType; //} var variable = new Variable { name = name, type = type, value = value }; Variables[name] = variable; return(variable); }
public int[] CreateLocals(out string[] names, out MelonObject[] initialValues) { var allVars = GetAllVariables(); var localTypes = new int[allVars.Count]; var localNames = new string[allVars.Count]; var localValues = new MelonObject[allVars.Count]; for (int i = 0; i < allVars.Count; i++) { var variable = allVars[i]; var typeKv = _engine.Types.FirstOrDefault(x => x.Value == variable.type.Type); localTypes[i] = typeKv.Key; localNames[i] = variable.name; localValues[i] = variable.value; } names = localNames; initialValues = localValues; return(localTypes); }
private void CallFunction(Context context, FunctionInstance functionInstance) { var arguments = new List <MelonObject>(); while (context.Arguments.Count > 0) { arguments.Add(context.Arguments.Pop()); } MelonObject self = null; if (context._stack.Count > 0) { self = context.Pop(); } var returnVal = functionInstance.Run(self, arguments.ToArray()); if (returnVal != null) { context.Push(returnVal); } }
private int[] GetInstructionsForLiteralValue(MelonObject value) { if (value is IntegerInstance integerInstance) { return(new int[] { (int)OpCode.LDINT, integerInstance.value }); } else if (value is FloatInstance decimalInstance) { // Split double value into 2 int32s var bit64 = BitConverter.DoubleToInt64Bits(decimalInstance.value); var left = (int)(bit64 >> 32); var right = (int)bit64; return(new int[] { (int)OpCode.LDFLO, left, right }); } else if (value is StringInstance stringInstance) { return(new int[] { (int)OpCode.LDSTR, GetString(stringInstance.value) }); } else if (value is BooleanInstance booleanInstance) { return(new int[] { (int)OpCode.LDBOOL, booleanInstance.value ? 1 : 0 }); } throw new NotImplementedException($"Literal instructions not implemented for {value.GetType()}"); //return new int[0]; }
public MelonEngine FastAdd(string name, MelonObject value) { GlobalEnvironment.AddVariable(name, value, new TypeReference(this, GetTypeFromValue(value))); return(this); }
public int Execute(Context context) { while (context.InstrCounter < context.Instructions.Length) { bool goNext = true; switch ((OpCode)context.Instruction) { case OpCode.LDBOOL: LoadBoolean(context); break; case OpCode.LDINT: LoadInteger(context); break; case OpCode.LDFLO: LoadDecimal(context); break; case OpCode.LDSTR: LoadString(context); break; case OpCode.LDTYP: LDTYP(context); break; case OpCode.LDARR: LDARR(context); break; case OpCode.ADD: case OpCode.MUL: case OpCode.CEQ: case OpCode.CLT: case OpCode.CGT: SolveOperation(context, (OpCode)context.Instruction); break; case OpCode.LDLOC: LDLOC(context); break; case OpCode.STLOC: STLOC(context); break; case OpCode.LDELEM: LDELEM(context); break; case OpCode.STELEM: STELEM(context); break; case OpCode.BR: BR(context); goNext = false; break; case OpCode.BRTRUE: BRTRUE(context); goNext = false; break; case OpCode.LDPRP: LDPRP(context); break; case OpCode.CALL: CALL(context); break; case OpCode.LDARG: LDARG(context); break; case OpCode.RET: RET(context); break; case OpCode.DUP: DUP(context); break; default: throw new MelonException($"Unknown instruction '{context.Instruction:X4}'"); } if (context._stack.Count > 0) { CompletionValue = context.Last(); } if (goNext) { context.Next(); } } return(0); }
public Property(MelonObject v) { value = v; }
//public void PrintHex() { // //byte[] result = new byte[_instructions.Length * sizeof(int)]; // //Buffer.BlockCopy(_instructions, 0, result, 0, result.Length); // //Console.WriteLine(BitConverter.ToString(result).Replace("-", "")); // for (int i = 0; i < _context.Instructions.Length; i++) { // Console.WriteLine(_context.Instructions[i].ToString("X8")); // } //} public void Print(ParseContext parseContext, MelonObject parent = null) { var context = _engine.CreateContext(parseContext); foreach (var kv in parseContext.Variables) { if (kv.Value.Variable.value is ScriptFunctionInstance scriptFunctionInstance && scriptFunctionInstance != parent) { //var functionNameBuilder = new StringBuilder("fn "); //if (scriptFunctionInstance.ReturnType != null) { // functionNameBuilder.Append(scriptFunctionInstance.ReturnType).Append(' '); //} //functionNameBuilder.Append(scriptFunctionInstance.Name).Append(' '); //functionNameBuilder.Append('(').Append(scriptFunctionInstance.ParameterTypes != null ? string.Join(",", (object[])scriptFunctionInstance.ParameterTypes.Select(x => x.Name)) : "").Append(')'); //Console.WriteLine(functionNameBuilder.ToString()); Console.WriteLine(scriptFunctionInstance.ToString()); Print(scriptFunctionInstance.ParseContext, kv.Value.Variable.value); } } Console.WriteLine("Variables {"); foreach (var kv in parseContext.Variables) { //var type = _engine.Types[context.LocalTypes[i]]; var genericStr = ""; if (kv.Value.Variable.type.GenericTypes?.Length > 0) { genericStr = $"<{string.Join(",", (object[])kv.Value.Variable.type.GenericTypes)}>"; } Console.WriteLine($"\t{kv.Key}: ({kv.Value.Type}) {kv.Value.Variable.name}: {(kv.Value.Variable.type.Type == _engine.functionType ? kv.Value.Variable.value.ToString() : kv.Value.Variable.type.ToString())}"); } Console.WriteLine("}\n"); int line = 0; for (int instrNum = 0; context.InstrCounter < context.Instructions.Length; instrNum++) { Console.Write($"MLN_{instrNum:x4}: "); string instructionString = ((OpCode)context.Instruction).ToString(); Console.Write(instructionString + " "); switch (context.Instruction) { case (int)OpCode.LDBOOL: context.Next(); Console.Write(context.Instruction == 1); break; case (int)OpCode.LDINT: context.Next(); Console.Write(context.Instruction); break; case (int)OpCode.LDFLO: context.Next(); int left = context.Instruction; context.Next(); int right = context.Instruction; Console.Write(GetDecimalValue(left, right).ToString("0.0##############################")); break; case (int)OpCode.LDSTR: context.Next(); Console.Write(_engine.Strings[context.Instruction]); break; case (int)OpCode.STLOC: context.Next(); Console.Write(context.Instruction); break; case (int)OpCode.LDLOC: context.Next(); Console.Write(context.Instruction); break; case (int)OpCode.STELEM: break; case (int)OpCode.LDELEM: break; case (int)OpCode.LDTYP: context.Next(); Console.Write(context.Instruction); break; case (int)OpCode.LDPRP: context.Next(); Console.Write(_engine.Strings[context.Instruction]); break; case (int)OpCode.BR: case (int)OpCode.BRTRUE: context.Next(); Console.Write($"MLN_{parseContext.BranchLines[context.Instruction]:x4}"); break; case (int)OpCode.DUP: break; } Console.WriteLine(); context.Next(); line++; } Console.WriteLine(); context.Reset(); }
private static MelonObject print(MelonObject self, Arguments arguments) { Console.WriteLine(string.Join(",", (object[])arguments.Values)); return(null); }