Skip to content

Commit

Permalink
Implemented more framework functions (#9) and error handling (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
Unknown6656 committed Jun 26, 2020
1 parent e232bf1 commit 0db7e4b
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 72 deletions.
19 changes: 9 additions & 10 deletions new/AutoItInterpreter/Extensibility/Interfaces.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
using System.Diagnostics.CodeAnalysis;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System;

using Unknown6656.AutoIt3.Extensibility;
using Unknown6656.AutoIt3.Runtime;
using Unknown6656.Common;
using System.Linq;
using System.Collections.Generic;

[assembly: AutoIt3Plugin]

Expand Down Expand Up @@ -111,21 +110,21 @@ public abstract class ProvidedNativeFunction
public abstract (int MinimumCount, int MaximumCount) ParameterCount { get; }


public abstract Union<InterpreterError, Variant>? Execute(NativeCallFrame frame, Variant[] args);

public override string ToString() => Name;

public static ProvidedNativeFunction Create(string name, int param_count, Func<NativeCallFrame, Variant[], Union<InterpreterError, Variant>?> @delegate) =>
public abstract FunctionReturnValue Execute(NativeCallFrame frame, Variant[] args);

public static ProvidedNativeFunction Create(string name, int param_count, Func<NativeCallFrame, Variant[], FunctionReturnValue> @delegate) =>
Create(name, param_count, param_count, @delegate);

public static ProvidedNativeFunction Create(string name, int min_param_count, int max_param_count, Func<NativeCallFrame, Variant[], Union<InterpreterError, Variant>?> @delegate, params Variant[] default_values) =>
public static ProvidedNativeFunction Create(string name, int min_param_count, int max_param_count, Func<NativeCallFrame, Variant[], FunctionReturnValue> @delegate, params Variant[] default_values) =>
new FromDelegate(@delegate, name, min_param_count, max_param_count, default_values);


internal sealed class FromDelegate
: ProvidedNativeFunction
{
private readonly Func<NativeCallFrame, Variant[], Union<InterpreterError, Variant>?> _exec;
private readonly Func<NativeCallFrame, Variant[], FunctionReturnValue> _exec;


public override string Name { get; }
Expand All @@ -135,15 +134,15 @@ internal sealed class FromDelegate
public override (int MinimumCount, int MaximumCount) ParameterCount { get; }


public FromDelegate(Func<NativeCallFrame, Variant[], Union<InterpreterError, Variant>?> exec, string name, int min_param_count, int max_param_count, params Variant[] default_values)
public FromDelegate(Func<NativeCallFrame, Variant[], FunctionReturnValue> exec, string name, int min_param_count, int max_param_count, params Variant[] default_values)
{
_exec = exec;
Name = name;
DefaultValues = default_values;
ParameterCount = (min_param_count, max_param_count);
}

public override Union<InterpreterError, Variant>? Execute(NativeCallFrame frame, Variant[] args)
public override FunctionReturnValue Execute(NativeCallFrame frame, Variant[] args)
{
List<Variant> a = new List<Variant>();

Expand Down
131 changes: 80 additions & 51 deletions new/AutoItInterpreter/Extensibility/Plugins.Au3Framework.Functions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,20 @@ public sealed class FrameworkFunctions
ProvidedNativeFunction.Create(nameof(ATan), 1, ATan),
ProvidedNativeFunction.Create(nameof(Cos), 1, Cos),
ProvidedNativeFunction.Create(nameof(Sin), 1, Sin),
ProvidedNativeFunction.Create(nameof(Exp), 1, Exp),
ProvidedNativeFunction.Create(nameof(Sqrt), 1, Sqrt),
ProvidedNativeFunction.Create(nameof(Tan), 1, Tan),
ProvidedNativeFunction.Create(nameof(Asc), 1, Asc),
ProvidedNativeFunction.Create(nameof(AscW), 1, AscW),
ProvidedNativeFunction.Create(nameof(Chr), 1, Chr),
ProvidedNativeFunction.Create(nameof(ChrW), 1, ChrW),
ProvidedNativeFunction.Create(nameof(Beep), 0, 2, Beep, 500m, 1000m),
//ProvidedNativeFunction.Create(nameof(), 1, ),
//ProvidedNativeFunction.Create(nameof(), 1, ),
//ProvidedNativeFunction.Create(nameof(), 1, ),
//ProvidedNativeFunction.Create(nameof(), 1, ),
//ProvidedNativeFunction.Create(nameof(), 1, ),
ProvidedNativeFunction.Create(nameof(BitAND), 2, 255, BitAND, Enumerable.Repeat((Variant)0xffffffff, 255).ToArray()),
ProvidedNativeFunction.Create(nameof(BitOR), 2, 255, BitOR),
ProvidedNativeFunction.Create(nameof(BitXOR), 2, 255, BitXOR),
ProvidedNativeFunction.Create(nameof(BitNOT), 1, BitNOT),
ProvidedNativeFunction.Create(nameof(BitShift), 2, BitShift),
ProvidedNativeFunction.Create(nameof(BitRotate), 1, 3, BitRotate, 1, "W"),
ProvidedNativeFunction.Create(nameof(ConsoleWrite), 1, ConsoleWrite),
ProvidedNativeFunction.Create(nameof(ConsoleWriteError), 1, ConsoleWriteError),
ProvidedNativeFunction.Create(nameof(ConsoleRead), 2, ConsoleRead),
Expand All @@ -36,9 +39,10 @@ public sealed class FrameworkFunctions
ProvidedNativeFunction.Create(nameof(Eval), 1, Eval),
ProvidedNativeFunction.Create(nameof(Assign), 2, 3, Assign),
ProvidedNativeFunction.Create(nameof(IsDeclared), 1, IsDeclared),
ProvidedNativeFunction.Create(nameof(SetError), 1, 3, SetError),
ProvidedNativeFunction.Create(nameof(SetExtended), 1, 2, SetExtended),
};


public FrameworkFunctions(Interpreter interpreter)
: base(interpreter)
{
Expand All @@ -61,56 +65,77 @@ private static Union<InterpreterError, AU3CallFrame> GetAu3Caller(CallFrame? fra
}


public static Union<InterpreterError, Variant> Abs(CallFrame frame, Variant[] args) => (Variant)Math.Abs(args[0].ToNumber());
public static FunctionReturnValue Abs(CallFrame frame, Variant[] args) => (Variant)Math.Abs(args[0].ToNumber());

public static FunctionReturnValue ACos(CallFrame frame, Variant[] args) => (Variant)Math.Acos((double)args[0].ToNumber());

public static Union<InterpreterError, Variant> ACos(CallFrame frame, Variant[] args) => (Variant)Math.Acos((double)args[0].ToNumber());
public static FunctionReturnValue ASin(CallFrame frame, Variant[] args) => (Variant)Math.Asin((double)args[0].ToNumber());

public static Union<InterpreterError, Variant> ASin(CallFrame frame, Variant[] args) => (Variant)Math.Asin((double)args[0].ToNumber());
public static FunctionReturnValue ATan(CallFrame frame, Variant[] args) => (Variant)Math.Atan((double)args[0].ToNumber());

public static Union<InterpreterError, Variant> ATan(CallFrame frame, Variant[] args) => (Variant)Math.Atan((double)args[0].ToNumber());
public static FunctionReturnValue Cos(CallFrame frame, Variant[] args) => (Variant)Math.Cos((double)args[0].ToNumber());

public static Union<InterpreterError, Variant> Cos(CallFrame frame, Variant[] args) => (Variant)Math.Cos((double)args[0].ToNumber());
public static FunctionReturnValue Sin(CallFrame frame, Variant[] args) => (Variant)Math.Sin((double)args[0].ToNumber());

public static Union<InterpreterError, Variant> Sin(CallFrame frame, Variant[] args) => (Variant)Math.Sin((double)args[0].ToNumber());
public static FunctionReturnValue Tan(CallFrame frame, Variant[] args) => (Variant)Math.Tan((double)args[0].ToNumber());

public static Union<InterpreterError, Variant> Tan(CallFrame frame, Variant[] args) => (Variant)Math.Tan((double)args[0].ToNumber());
public static FunctionReturnValue Exp(CallFrame frame, Variant[] args) => (Variant)Math.Exp((double)args[0].ToNumber());

public static Union<InterpreterError, Variant> Asc(CallFrame frame, Variant[] args) => (Variant)(byte)args[0].ToString().FirstOrDefault();
public static FunctionReturnValue Sqrt(CallFrame frame, Variant[] args) => (Variant)Math.Sqrt((double)args[0].ToNumber());

public static Union<InterpreterError, Variant> AscW(CallFrame frame, Variant[] args) => (Variant)(int)args[0].ToString().FirstOrDefault();
public static FunctionReturnValue Asc(CallFrame frame, Variant[] args) => (Variant)(byte)args[0].ToString().FirstOrDefault();

public static Union<InterpreterError, Variant> Chr(CallFrame frame, Variant[] args) => (Variant)((char)(int)args[0]).ToString();
public static FunctionReturnValue AscW(CallFrame frame, Variant[] args) => (Variant)(int)args[0].ToString().FirstOrDefault();

public static Union<InterpreterError, Variant> ChrW(CallFrame frame, Variant[] args) => (Variant)((char)(byte)args[0]).ToString();
public static FunctionReturnValue Chr(CallFrame frame, Variant[] args) => (Variant)((char)(int)args[0]).ToString();

public static Union<InterpreterError, Variant> Beep(CallFrame frame, Variant[] args)
public static FunctionReturnValue ChrW(CallFrame frame, Variant[] args) => (Variant)((char)(byte)args[0]).ToString();

public static FunctionReturnValue Beep(CallFrame frame, Variant[] args)
{
Console.Beep((int)args[0], (int)args[1]);

return Variant.True;
}

//public static Union<InterpreterError, Variant>(CallFrame frame, Variant[] args)
//{
//}
public static FunctionReturnValue BitAND(CallFrame frame, Variant[] args) => args.Aggregate(Variant.BitwiseAnd);

//public static Union<InterpreterError, Variant>(CallFrame frame, Variant[] args)
//{
//}
public static FunctionReturnValue BitOR(CallFrame frame, Variant[] args) => args.Aggregate(Variant.BitwiseOr);

//public static Union<InterpreterError, Variant>(CallFrame frame, Variant[] args)
//{
//}
public static FunctionReturnValue BitNOT(CallFrame frame, Variant[] args) => ~args[0];

//public static Union<InterpreterError, Variant>(CallFrame frame, Variant[] args)
//{
//}
public static FunctionReturnValue BitXOR(CallFrame frame, Variant[] args) => args.Aggregate(Variant.BitwiseOr);

//public static Union<InterpreterError, Variant>(CallFrame frame, Variant[] args)
//{
//}
public static FunctionReturnValue BitShift(CallFrame frame, Variant[] args) => args[0] >> (int)args[1];

public static Union<InterpreterError, Variant> ConsoleWriteError(CallFrame frame, Variant[] args)
public static FunctionReturnValue BitRotate(CallFrame frame, Variant[] args)
{
Variant rotate(int size)
{
int amount = (int)args[1];
long value = (long)args[0];
long rotmask = -1L >> (64 - size);
long @static = value & ~rotmask;
long variable = value & rotmask;
long rotated = (variable << amount) | (variable >> (size - amount));

rotated &= rotmask;
rotated |= @static;

return rotated;
}

return args[2].ToString().ToUpperInvariant() switch
{
"B" => rotate(8),
"W" => rotate(16),
"D" => rotate(32),
"Q" => rotate(64),
_ => FunctionReturnValue.Error(-1),
};
}

public static FunctionReturnValue ConsoleWriteError(CallFrame frame, Variant[] args)
{
string s = args[0].ToString();

Expand All @@ -119,7 +144,7 @@ public static Union<InterpreterError, Variant> ConsoleWriteError(CallFrame frame
return Variant.FromNumber(s.Length);
}

public static Union<InterpreterError, Variant> ConsoleWrite(CallFrame frame, Variant[] args)
public static FunctionReturnValue ConsoleWrite(CallFrame frame, Variant[] args)
{
string s = args[0].ToString();

Expand All @@ -128,7 +153,7 @@ public static Union<InterpreterError, Variant> ConsoleWrite(CallFrame frame, Var
return Variant.FromNumber(s.Length);
}

public static Union<InterpreterError, Variant> ConsoleRead(CallFrame frame, Variant[] args)
public static FunctionReturnValue ConsoleRead(CallFrame frame, Variant[] args)
{
bool peek = args[0].ToBoolean();
bool binary = args[1].ToBoolean();
Expand All @@ -138,7 +163,7 @@ public static Union<InterpreterError, Variant> ConsoleRead(CallFrame frame, Vari
throw new NotImplementedException();
}

public static Union<InterpreterError, Variant> MsgBox(CallFrame frame, Variant[] args)
public static FunctionReturnValue MsgBox(CallFrame frame, Variant[] args)
{
decimal flag = args[0].ToNumber();
string title = args[1].ToString();
Expand All @@ -152,20 +177,20 @@ public static Union<InterpreterError, Variant> MsgBox(CallFrame frame, Variant[]
throw new NotImplementedException();
}

private static Union<InterpreterError, Variant> Execute(CallFrame frame, Variant[] args) =>
GetAu3Caller(frame, nameof(Execute)).Match<Union<InterpreterError, Variant>>(err => err, au3 => au3.ProcessAsVariant(args[0].ToString()));
public static FunctionReturnValue Execute(CallFrame frame, Variant[] args) =>
GetAu3Caller(frame, nameof(Execute)).Match<FunctionReturnValue>(err => err, au3 => au3.ProcessAsVariant(args[0].ToString()));

private static Union<InterpreterError, Variant> Eval(CallFrame frame, Variant[] args) =>
GetAu3Caller(frame, nameof(Execute)).Match<Union<InterpreterError, Variant>>(err => err, au3 =>
public static FunctionReturnValue Eval(CallFrame frame, Variant[] args) =>
GetAu3Caller(frame, nameof(Execute)).Match<FunctionReturnValue>(err => err, au3 =>
{
if (au3.VariableResolver.TryGetVariable(args[0].ToString(), out Variable? variable))
return variable.Value;
return InterpreterError.WellKnown(au3.CurrentLocation, "error.undeclared_variable", args[0]);
});

private static Union<InterpreterError, Variant> Assign(CallFrame frame, Variant[] args) =>
GetAu3Caller(frame, nameof(Execute)).Match<Union<InterpreterError, Variant>>(err => err, au3 =>
public static FunctionReturnValue Assign(CallFrame frame, Variant[] args) =>
GetAu3Caller(frame, nameof(Execute)).Match<FunctionReturnValue>(err => err, au3 =>
{
string name = args[0].ToString();
Variant data = args[1];
Expand All @@ -190,15 +215,19 @@ private static Union<InterpreterError, Variant> Assign(CallFrame frame, Variant[
return Variant.True;
});

private static Union<InterpreterError, Variant> IsDeclared(CallFrame frame, Variant[] args) =>
GetAu3Caller(frame, nameof(Execute)).Match<Union<InterpreterError, Variant>>(err => err, au3 =>
public static FunctionReturnValue IsDeclared(CallFrame frame, Variant[] args) =>
GetAu3Caller(frame, nameof(Execute)).Match<FunctionReturnValue>(err => err, au3 =>
{
if (au3.VariableResolver.TryGetVariable(args[0].ToString(), out Variable? variable))
return (Variant)(variable.IsGlobal ? 1 : -1);
else
return Variant.Zero;
});

public static FunctionReturnValue SetExtended(CallFrame frame, Variant[] args) => frame.SetExtended((int)args[0], args[1]);

public static FunctionReturnValue SetError(CallFrame frame, Variant[] args) => frame.SetError((int)args[0], (int)args[1], args[2]);

[Flags]
private enum AssignFlags
: int
Expand All @@ -218,7 +247,7 @@ public sealed class AdditionalFunctions
ProvidedNativeFunction.Create(nameof(ACosh), 1, ACosh),
ProvidedNativeFunction.Create(nameof(ASinh), 1, ASinh),
ProvidedNativeFunction.Create(nameof(ATanh), 1, ATanh),
ProvidedNativeFunction.Create(nameof(ConsoleWriteLine), 0, 1, ConsoleWriteLine),
ProvidedNativeFunction.Create(nameof(ConsoleWriteLine), 0, 1, ConsoleWriteLine, ""),
ProvidedNativeFunction.Create(nameof(ConsoleReadLine), 0, ConsoleReadLine),
};

Expand All @@ -228,15 +257,15 @@ public AdditionalFunctions(Interpreter interpreter)
{
}

public static Union<InterpreterError, Variant> ACosh(CallFrame frame, Variant[] args) => (Variant)Math.Acosh((double)args[0].ToNumber());
public static FunctionReturnValue ACosh(CallFrame frame, Variant[] args) => (Variant)Math.Acosh((double)args[0].ToNumber());

public static Union<InterpreterError, Variant> ASinh(CallFrame frame, Variant[] args) => (Variant)Math.Asinh((double)args[0].ToNumber());
public static FunctionReturnValue ASinh(CallFrame frame, Variant[] args) => (Variant)Math.Asinh((double)args[0].ToNumber());

public static Union<InterpreterError, Variant> ATanh(CallFrame frame, Variant[] args) => (Variant)Math.Atanh((double)args[0].ToNumber());
public static FunctionReturnValue ATanh(CallFrame frame, Variant[] args) => (Variant)Math.Atanh((double)args[0].ToNumber());

public static Union<InterpreterError, Variant> ConsoleWriteLine(CallFrame frame, Variant[] args) =>
public static FunctionReturnValue ConsoleWriteLine(CallFrame frame, Variant[] args) =>
FrameworkFunctions.ConsoleWrite(frame, new[] { (args.Length > 0 ? args[0] : "") & "\r\n" });

public static Union<InterpreterError, Variant> ConsoleReadLine(CallFrame frame, Variant[] args) => (Variant)Console.ReadLine();
public static FunctionReturnValue ConsoleReadLine(CallFrame frame, Variant[] args) => (Variant)Console.ReadLine();
}
}
12 changes: 6 additions & 6 deletions new/AutoItInterpreter/Extensibility/Plugins.Debugging.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,15 +192,15 @@ private static Variant SerializePrint(CallFrame frame, IDictionary<string, objec
return Variant.Zero;
}

private static Union<InterpreterError, Variant> DebugVar(CallFrame frame, Variant[] args) => SerializePrint(frame, GetVariableInfo(args[0].AssignedTo), args[0].AssignedTo);
private static FunctionReturnValue DebugVar(CallFrame frame, Variant[] args) => SerializePrint(frame, GetVariableInfo(args[0].AssignedTo), args[0].AssignedTo);

private static Union<InterpreterError, Variant> DebugCallFrame(CallFrame frame, Variant[] args) => SerializePrint(frame, GetCallFrameInfo(frame), "Call Frame");
private static FunctionReturnValue DebugCallFrame(CallFrame frame, Variant[] args) => SerializePrint(frame, GetCallFrameInfo(frame), "Call Frame");

private static Union<InterpreterError, Variant> DebugThread(CallFrame frame, Variant[] _) => SerializePrint(frame, GetThreadInfo(frame.CurrentThread), frame.CurrentThread);
private static FunctionReturnValue DebugThread(CallFrame frame, Variant[] _) => SerializePrint(frame, GetThreadInfo(frame.CurrentThread), frame.CurrentThread);

private static Union<InterpreterError, Variant> DebugAllVars(CallFrame frame, Variant[] _) => SerializePrint(frame, GetAllVariables(frame.Interpreter), frame.Interpreter);
private static FunctionReturnValue DebugAllVars(CallFrame frame, Variant[] _) => SerializePrint(frame, GetAllVariables(frame.Interpreter), frame.Interpreter);

private static Union<InterpreterError, Variant> DebugAllVarsCompact(CallFrame frame, Variant[] _)
private static FunctionReturnValue DebugAllVarsCompact(CallFrame frame, Variant[] _)
{
List<VariableScope> scopes = new List<VariableScope> { frame.Interpreter.VariableResolver };
int count;
Expand Down Expand Up @@ -246,7 +246,7 @@ orderby name ascending
return Variant.Zero;
}

private static Union<InterpreterError, Variant> DebugAllThreads(CallFrame frame, Variant[] _)
private static FunctionReturnValue DebugAllThreads(CallFrame frame, Variant[] _)
{
// TODO

Expand Down
Loading

0 comments on commit 0db7e4b

Please sign in to comment.