private object EX_If(LispRuntimeCommand cmd, LispList program) { CheckParameterCount(cmd, program, 2, 3); LispItem conditionalStatement = program.items[1]; LispItem trueStatement = program.items[2]; // run the condition object conditionResult = Run(conditionalStatement); CheckParameterType(cmd, 1, program, conditionResult, typeof(bool), false); if ((bool)conditionResult) { return(Run(trueStatement)); } else if (program.items.Count == 4) { LispItem falseStatement = program.items[3]; return(Run(falseStatement)); } else { return(null); } }
private object EX_While(LispRuntimeCommand cmd, LispList program) { object retVal = null; if (program.items.Count < 2) { throw new LispParseException($"'{cmd.CommandName}' command must have at least 1 parameter. Line: {program.line}:{program.position}"); } LispItem conditionalStatement = program.items[1]; // body of the while loop start: object conditionalResult = Run(conditionalStatement); CheckParameterType(cmd, 1, program, conditionalResult, typeof(bool), false); if ((bool)conditionalResult) { for (int i = 2; i < program.items.Count; i++) { retVal = Run(program.items[i]); } goto start; } return(retVal); }
private object Ex_LessThanEqual(LispRuntimeCommand cmd, LispList program) { CheckParameterCount(cmd, program, 2); long a = GetLongValue(cmd, program, 1, false); long b = GetLongValue(cmd, program, 2, false); return(a <= b); }
private object EX_Not(LispRuntimeCommand cmd, LispList program) { CheckParameterCount(cmd, program, 1); object result = Run(program.items[1]); CheckParameterType(cmd, 1, program, result, typeof(bool), false); return(!((bool)result)); }
public void RegisterCommand(LispRuntimeCommand command) { if (_commands.ContainsKey(command.CommandName)) { throw new Exception(string.Format("Command '{0}' already exits cannot override command.", command.CommandName)); } else { _commands.Add(command.CommandName, command); _logger.LogIf(_categories.ScriptLogging, Level.Debug, $"Registered command: {command.CommandName}"); } }
private object Ex_GetArg(LispRuntimeCommand cmd, LispList list) { CheckParameterCount(cmd, list, 1, 2); string arg = Run <string>(list.items[1]); object defaultValue = null; if (list.items.Count > 2) { defaultValue = Run <object>(list.items[2]); } else { defaultValue = string.Empty; } var args = Environment.GetCommandLineArgs(); string returnValue = null; for (int i = 0; i < args.Length; i++) { var a = args[i]; if (a == arg) { if (i + 1 < args.Length) { returnValue = args[i + 1]; } else { break; } } } if (returnValue == null) { return(defaultValue); } switch (defaultValue) { case double d: return(double.Parse(returnValue)); case int i: return(int.Parse(returnValue)); default: return(returnValue); } }
private object Ex_Assert(LispRuntimeCommand cmd, LispList list) { CheckParameterCount(cmd, list, 1); bool isOkay = Run <bool>(list.items[1]); if (isOkay) { return(true); } else { throw new Exception($"Failed Assert on {list.line}:{list.position}"); } }
protected static void CheckParameterCount(LispRuntimeCommand cmd, LispList program, params int[] expectedCounts) { if (!expectedCounts.Contains(program.items.Count - 1)) { if (expectedCounts.Length == 1) { throw new LispParseException($"'{cmd.CommandName}' command must have exactly {expectedCounts[0]} parameters. Line: {program.line}:{program.position}"); } else { throw new LispParseException($"'{cmd.CommandName}' command expects {expectedCounts.ToDelimited("","", " or ")} parameters. Line: {program.line}:{program.position}"); } } }
protected long GetLongValue(LispRuntimeCommand cmd, LispList program, int index, bool allowNull) { object v = Run(program.items[index]); CheckParameterType(cmd, index, program, v, typeof(long), allowNull); if (null == v) { return(0); } else { return((long)v); } }
private object EX_SetVariable(LispRuntimeCommand cmd, LispList program) { CheckParameterCount(cmd, program, 2); // get parameters string variableName = Run(program.items[1]) as string; object variableValue = Run(program.items[2]); CheckParameterType(cmd, 1, program, variableName, typeof(string), false); _var[variableName] = variableValue; return(variableValue); }
private object Ex_Or(LispRuntimeCommand cmd, LispList program) { CheckParameterCount(cmd, program, 2); object leftResult = Run(program.items[1]); CheckParameterType(cmd, 1, program, leftResult, typeof(bool), false); if ((bool)leftResult) { return(true); } object rightResult = Run(program.items[2]); CheckParameterType(cmd, 2, program, leftResult, typeof(bool), false); return((bool)rightResult); }
private object Ex_Sub(LispRuntimeCommand cmd, LispList program) { if (program.items.Count - 1 < 2) { throw new LispParseException($"'{cmd.CommandName}' command must have at least 2 parameters. Line: {program.line}:{program.position}"); } long accumulator = GetLongValue(cmd, program, 1, false); for (int i = 2; i < program.items.Count; i++) { long number = GetLongValue(cmd, program, i, false); accumulator -= number; } return(accumulator); }
private object EX_GetVariableMember(LispRuntimeCommand cmd, LispList program) { CheckParameterCount(cmd, program, 2); int c = 1; object instance = Run(program.items[c++]); string name = Run <string>(program.items[c++]); var member = instance.GetType().GetMember(name)[0]; switch (member) { case PropertyInfo property: return(property.GetValue(instance)); case FieldInfo field: return(field.GetValue(instance)); } return(null); }
private object EX_Equal(LispRuntimeCommand cmd, LispList program) { CheckParameterCount(cmd, program, 2); object value1 = Run(program.items[1]); object value2 = Run(program.items[2]); if (value1 == value2) { return(true); } if (value1 != null) { return(value1.Equals(value2)); } return(false); }
private object EX_GetEnvironment(LispRuntimeCommand cmd, LispList program) { CheckParameterCount(cmd, program, 1); string variableName = Run(program.items[1]) as string; CheckParameterType(cmd, 1, program, variableName, typeof(string), false); string value = null; if (_env.TryGetValue(variableName, out value)) { return(value); } else { var item = program.items[1]; throw new LispParseException($"GetEnvironment command failed. Variable '{variableName}' doesn't exist. Line: {item.line}:{item.position}"); } }
protected static void CheckParameterType(LispRuntimeCommand cmd, int paramIndex, LispList program, object item, Type expectedType, bool allowNull) { if (null == item) { if (allowNull) { return; } else { throw new Exception(string.Format("'{0}' parameter {1} cannot be null. Line: {2}:{3}", cmd.CommandName, paramIndex, program.line, program.position)); } } if (item.GetType() != expectedType) { throw new Exception(string.Format("'{0}' expected parameter {1} to be of type {2}. Line: {3}:{4}", cmd.CommandName, paramIndex, expectedType, program.line, program.position)); } }
private object EX_Loop(LispRuntimeCommand cmd, LispList program) { object retVal = null; if (program.items.Count < 3) { throw new LispParseException($"'{cmd.CommandName}' command must have at least 2 parameters. Line: {program.line}:{program.position}"); } long loopCount = GetLongValue(cmd, program, 1, false); for (long i = 0; i < loopCount; i++) { for (int j = 2; j < program.items.Count; j++) { retVal = Run(program.items[j]); } } return(retVal); }
private object Ex_ForEach(LispRuntimeCommand cmd, LispList list) { if (list.items.Count < 3) { throw new LispParseException($"'{cmd.CommandName}' command expects more than 1 parameters. Line: {list.line}:{list.position}"); } string variableName = Run <string>(list.items[1]); string[] loopItems = Run <string[]>(list.items[2]); foreach (string variableValue in loopItems) { SetVariable(variableName, variableValue); for (int i = 2; i < list.items.Count; i++) { Run(list.items[i]); } } return(null); }
private object Ex_Array(LispRuntimeCommand cmd, LispList list) { return(list.items.Skip(1).Select(i => Run <string>(i)).ToArray()); }