Skip to content

Commit

Permalink
Fixed tuples, added lambda and func support to 'is' operator and adde…
Browse files Browse the repository at this point in the history
…d ssl + credentials support to the smtp class
  • Loading branch information
zdimension committed Oct 20, 2015
1 parent c205ca6 commit e1019d4
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 19 deletions.
3 changes: 2 additions & 1 deletion src/Hassium/HassiumObjects/HassiumObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace Hassium.HassiumObjects

public class HassiumObject : IFunction
{
private readonly Dictionary<string, HassiumObject> _attributes;
private Dictionary<string, HassiumObject> _attributes;

public bool IsInstance { get; set; }

Expand All @@ -50,6 +50,7 @@ public class HassiumObject : IFunction
public Dictionary<string, HassiumObject> Attributes
{
get { return _attributes; }
protected set { _attributes = value; }
}

public HassiumObject()
Expand Down
27 changes: 20 additions & 7 deletions src/Hassium/HassiumObjects/HassiumTuple.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,34 +41,47 @@ public class HassiumTuple: HassiumObject

private int position { get; set; }


public List<HassiumObject> Items { get; private set; }

public HassiumTuple(TupleNode value, Hassium.Interpreter.Interpreter interpreter) : this(value.Children[0].Children.Select((v, i) => (HassiumObject)v.Visit(interpreter)).ToList(), interpreter)
{
TupleNode = value;
}




public HassiumTuple(IList<HassiumObject> value, Hassium.Interpreter.Interpreter interpreter)
{
for (position = 0; position < value.Count; position++)
Attributes.Add("Item" + position, value[position]);
Items = value.ToList();

refresh();

Attributes.Add("add", new InternalFunction(add, -1));
Attributes.Add("remove", new InternalFunction(remove, -1));
}

private void refresh()
{
Attributes =
Items.Select((item, index) => new KeyValuePair<string, HassiumObject>("Item" + index, item))
.ToDictionary(x => x.Key, x => x.Value);
}

private HassiumObject add(HassiumObject[] args)
{
foreach (HassiumObject arg in args)
Attributes.Add("Item" + position++, arg);
Items.AddRange(args);

refresh();

return null;
}

private HassiumObject remove(HassiumObject[] args)
{
foreach (HassiumObject arg in args)
Attributes.Remove(((HassiumString)arg).Value);
args.All(x => Items.Remove(x));

refresh();

return null;
}
Expand Down
43 changes: 42 additions & 1 deletion src/Hassium/HassiumObjects/Networking/Mail/HassiumSmtpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
using System.Collections.Generic;
using System.Net.Mail;
using System.Linq;
using System.Net;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
using System.Text;
using Hassium.Interpreter;
using Hassium.Functions;
Expand All @@ -41,7 +43,46 @@ public class HassiumSmtpClient: HassiumObject
public HassiumSmtpClient(HassiumString server, HassiumInt port)
{
Value = new SmtpClient(server.ToString(), port.Value);
Attributes.Add("send", new InternalFunction(send, new int[] { 1, 4 }));
Attributes.Add("send", new InternalFunction(send, new int[] {1, 4}));

Attributes.Add("credentials", new HassiumProperty("credentials",
x =>
{
var cred = new HassiumObject();
cred.Attributes.Add("username",
new HassiumProperty("username", y => (Value.Credentials as NetworkCredential).UserName,
(self, y) =>
{
Value.Credentials =
new NetworkCredential(y[0].ToString(),
(Value.Credentials as NetworkCredential).Password);
return null;
}));
cred.Attributes.Add("password",
new HassiumProperty("password", y => (Value.Credentials as NetworkCredential).Password,
(self, y) =>
{
Value.Credentials =
new NetworkCredential((Value.Credentials as NetworkCredential).UserName,
y[0].ToString());
return null;
}));

return cred;
},
(self, y) =>
{
if(y[0] is HassiumTuple)
{
var tuple = (HassiumTuple) y[0];
Value.Credentials = new NetworkCredential(tuple.Items[0].ToString(), tuple.Items[1].ToString());
}

return null;
}));

Attributes.Add("enableSsl",
new HassiumProperty("enableSsl", x => Value.EnableSsl, (self, x) => Value.EnableSsl = x[0].HBool()));
}

private HassiumObject send(HassiumObject[] args)
Expand Down
18 changes: 12 additions & 6 deletions src/Hassium/Interpreter/HassiumMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public string Name
get { return FuncNode.Name; }
}

public bool IsLambda { get; private set; }

public bool IsStatic
{
get { return !FuncNode.Parameters.Contains("this"); }
Expand All @@ -57,22 +59,25 @@ public bool IsConstructor
get { return Name == "new"; }
}

public HassiumMethod(Interpreter interpreter, FuncNode funcNode, LocalScope localScope, HassiumObject self)
public HassiumMethod(Interpreter interpreter, FuncNode funcNode, LocalScope localScope, HassiumObject self, bool lambda = false) : this(interpreter, funcNode, (StackFrame)null, self, lambda)
{
SelfReference = self;
/*SelfReference = self;
Interpreter = interpreter;
FuncNode = funcNode;
LocalScope = localScope;
stackFrame = null;
IsLambda = lambda;*/
LocalScope = localScope;
}

public HassiumMethod(Interpreter interpreter, FuncNode funcNode, StackFrame stackFrame, HassiumObject self)
public HassiumMethod(Interpreter interpreter, FuncNode funcNode, StackFrame stackFrame, HassiumObject self, bool lambda = false)
{
SelfReference = self;
Interpreter = interpreter;
FuncNode = funcNode;
LocalScope = stackFrame == null ? null : stackFrame.Scope;
this.stackFrame = stackFrame;
IsLambda = lambda;
}

public static implicit operator HassiumEventHandler(HassiumMethod mt)
Expand All @@ -95,7 +100,8 @@ public override HassiumObject Invoke(params HassiumObject[] args)
if (parms.Contains("this")) parms.Remove("this");

if (parms.Count != args.Length)
throw new Exception("Incorrect arguments for function " + Name + ": Expected " + parms.Count + " args, got " + args.Length);
throw new Exception("Incorrect arguments for " +
(IsLambda ? "lambda function" : "function " + Name ) + ": Expected " + parms.Count + " args, got " + args.Length);

for (int x = 0; x < parms.Count; x++)
stackFrame.Locals[parms[x]] = args[x];
Expand All @@ -120,8 +126,8 @@ public override HassiumObject Invoke(params HassiumObject[] args)

public override string ToString()
{
return string.Format("[HassiumMethod: {0}`{1} SelfReference={2}]", Name, (FuncNode.InfParams ? "i" : FuncNode.Parameters.Count.ToString()),
SelfReference ?? "null");
return string.Format("[HassiumMethod: {0}`{1} SelfReference={2} {3}]", Name, (FuncNode.InfParams ? "i" : FuncNode.Parameters.Count.ToString()),
SelfReference ?? "null", IsLambda ? "Lambda" : "");
}

/// <summary>
Expand Down
31 changes: 30 additions & 1 deletion src/Hassium/Interpreter/Interpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using Hassium.Functions;
Expand Down Expand Up @@ -293,6 +294,30 @@ private HassiumObject interpretBinaryOp(BinOpNode node)
if(node.Right is IdentifierNode)
{
var name = node.Right.ToString().ToLower();
if (name.Contains("`"))
{
var n = name.Split('`')[0];
var pnums = name.Split('`')[1];
if (pnums == "")
{
throw new ParseException("Expected argument number", node.Right.Position + n.Length + 1);
}
var pnum = -1;
try
{
pnum = int.Parse(pnums);
}
catch
{
throw new ParseException("Invalid argument number: " + pnums,
node.Right.Position + n.Length + 1);
}
return target is HassiumMethod &&
(n == "lambda"
? ((HassiumMethod) target).IsLambda
: n == "func" && !((HassiumMethod) target).IsLambda) &&
((HassiumMethod) target).FuncNode.Parameters.Count == pnum;
}
switch (name)
{
case "string":
Expand Down Expand Up @@ -324,6 +349,10 @@ private HassiumObject interpretBinaryOp(BinOpNode node)
return true;
case "tuple":
return target is HassiumTuple;
case "func":
return target is HassiumMethod && !((HassiumMethod)target).IsLambda;
case "lambda":
return target is HassiumMethod && ((HassiumMethod) target).IsLambda;
}
}
else
Expand Down Expand Up @@ -1367,7 +1396,7 @@ public object Accept(LambdaFuncNode node)
return true;
});
}
return new HassiumMethod(this, (FuncNode) funcNode, stackFrame, null);
return new HassiumMethod(this, (FuncNode) funcNode, stackFrame, null, true);
}

public object Accept(MemberAccessNode node)
Expand Down
10 changes: 7 additions & 3 deletions src/Hassium/Parser/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1171,12 +1171,16 @@ private static AstNode ParseTerm(Parser parser)
switch (curt.Value.ToString())
{
case "lambda":
return parseLambda(parser);
return parser.PreviousToken(-1).TokenClass != TokenType.LParen
? new IdentifierNode(position, parser.ExpectToken(TokenType.Identifier).Value.ToString())
: parseLambda(parser);
case "new":
return ParseInstance(parser);
case "tuple":
if(parser.PreviousToken(-1).TokenClass == TokenType.LParen
|| (parser.PreviousToken(-1).TokenClass == TokenType.Identifier && parser.PreviousToken(-2).TokenClass == TokenType.LParen)) return parseTuple(parser);
if (parser.PreviousToken(-1).TokenClass == TokenType.LParen
||
(parser.PreviousToken(-1).TokenClass == TokenType.Identifier &&
parser.PreviousToken(-2).TokenClass == TokenType.LParen)) return parseTuple(parser);
break;
}
return new IdentifierNode(position, parser.ExpectToken(TokenType.Identifier).Value.ToString());
Expand Down

0 comments on commit e1019d4

Please sign in to comment.