Parser stuff
This commit is contained in:
parent
7acaa9df76
commit
abbd4a74ef
25 changed files with 1044 additions and 32 deletions
91
ShintenScriptTest/EvaluationTest.cs
Normal file
91
ShintenScriptTest/EvaluationTest.cs
Normal file
|
@ -0,0 +1,91 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using ShintenScript;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ShintenScriptTest
|
||||
{
|
||||
[TestClass]
|
||||
public class EvaluationTest
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestBlock()
|
||||
{
|
||||
IASTNode ast = new ASTNodeBlock(new List<IASTNode>()
|
||||
{
|
||||
new ASTNodeLiteral(1f),
|
||||
new ASTNodeLiteral(true),
|
||||
new ASTNodeLiteral(5f)
|
||||
});
|
||||
|
||||
Assert.AreEqual(SSType.real, ast.Type());
|
||||
|
||||
Func<ExecutionContext, float> func = (Func<ExecutionContext, float>)ast.CreateFunction();
|
||||
|
||||
Assert.AreEqual(5f, func(null));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestAdd()
|
||||
{
|
||||
IASTNode ast = new ASTNodeAdd(new ASTNodeLiteral(2f), new ASTNodeLiteral(3f));
|
||||
|
||||
Assert.AreEqual(SSType.real, ast.Type());
|
||||
|
||||
Func<ExecutionContext, float> func = (Func<ExecutionContext, float>)ast.CreateFunction();
|
||||
|
||||
Assert.AreEqual(5f, func(null));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestMul()
|
||||
{
|
||||
IASTNode ast = new ASTNodeMultiply(new ASTNodeLiteral(2f), new ASTNodeLiteral(3f));
|
||||
|
||||
Assert.AreEqual(SSType.real, ast.Type());
|
||||
|
||||
Func<ExecutionContext, float> func = (Func<ExecutionContext, float>)ast.CreateFunction();
|
||||
|
||||
Assert.AreEqual(6f, func(null));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestSub()
|
||||
{
|
||||
IASTNode ast = new ASTNodeSubtract(new ASTNodeLiteral(2f), new ASTNodeLiteral(3f));
|
||||
|
||||
Assert.AreEqual(SSType.real, ast.Type());
|
||||
|
||||
Func<ExecutionContext, float> func = (Func<ExecutionContext, float>)ast.CreateFunction();
|
||||
|
||||
Assert.AreEqual(-1f, func(null));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestDiv()
|
||||
{
|
||||
IASTNode ast = new ASTNodeDivide(new ASTNodeLiteral(7f), new ASTNodeLiteral(2f));
|
||||
|
||||
Assert.AreEqual(SSType.real, ast.Type());
|
||||
|
||||
Func<ExecutionContext, float> func = (Func<ExecutionContext, float>)ast.CreateFunction();
|
||||
|
||||
Assert.AreEqual(3.5f, func(null));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestNegative()
|
||||
{
|
||||
IASTNode ast = new ASTNodeNegative(new ASTNodeLiteral(7f));
|
||||
|
||||
Assert.AreEqual(SSType.real, ast.Type());
|
||||
|
||||
Func<ExecutionContext, float> func = (Func<ExecutionContext, float>)ast.CreateFunction();
|
||||
|
||||
Assert.AreEqual(-7f, func(null));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ namespace ShintenScriptTest
|
|||
1.5e6
|
||||
2.4e-6
|
||||
|
||||
;
|
||||
( ) { }
|
||||
+ - * /
|
||||
> < == >= <= !=
|
||||
|
@ -36,6 +37,7 @@ namespace ShintenScriptTest
|
|||
new Token { type = Token.Type.NUMBER, data = 1.5e6f },
|
||||
new Token { type = Token.Type.NUMBER, data = 2.4e-6f },
|
||||
|
||||
new Token { type = Token.Type.SEMICOLON },
|
||||
new Token { type = Token.Type.LPAREN },
|
||||
new Token { type = Token.Type.RPAREN },
|
||||
new Token { type = Token.Type.LBRACE },
|
||||
|
@ -59,8 +61,18 @@ namespace ShintenScriptTest
|
|||
new Token { type = Token.Type.IF },
|
||||
new Token { type = Token.Type.WHILE },
|
||||
new Token { type = Token.Type.FN },
|
||||
}));
|
||||
}
|
||||
|
||||
new Token { type = Token.Type.EOF },
|
||||
[TestMethod]
|
||||
public void TestHexExponent()
|
||||
{
|
||||
Lexer lexer = new Lexer(@"0xcafe-1337");
|
||||
|
||||
Assert.IsTrue(lexer.TokenStream().SequenceEqual(new Token[] {
|
||||
new Token { type = Token.Type.NUMBER, data = 51966f },
|
||||
new Token { type = Token.Type.MINUS },
|
||||
new Token { type = Token.Type.NUMBER, data = 1337f },
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
153
ShintenScriptTest/ParserTest.cs
Normal file
153
ShintenScriptTest/ParserTest.cs
Normal file
|
@ -0,0 +1,153 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using ShintenScript;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ShintenScriptTest
|
||||
{
|
||||
[TestClass]
|
||||
public class ParserTest
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestBlock()
|
||||
{
|
||||
Lexer lexer = new ScaffoldLexer(new Token[]
|
||||
{
|
||||
new Token { type = Token.Type.LBRACE },
|
||||
new Token { type = Token.Type.NUMBER, data = 1f },
|
||||
new Token { type = Token.Type.NUMBER, data = 2f },
|
||||
new Token { type = Token.Type.NUMBER, data = 3f },
|
||||
new Token { type = Token.Type.RBRACE },
|
||||
});
|
||||
|
||||
IASTNode ast = new Parser(lexer).ParseExpression();
|
||||
|
||||
if (ast is ASTNodeBlock block)
|
||||
{
|
||||
Assert.AreEqual(3, block.statements.Count);
|
||||
Assert.IsInstanceOfType(block.statements[0], typeof(ASTNodeLiteral));
|
||||
Assert.IsInstanceOfType(block.statements[1], typeof(ASTNodeLiteral));
|
||||
Assert.IsInstanceOfType(block.statements[2], typeof(ASTNodeLiteral));
|
||||
}
|
||||
else Assert.Fail();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestComparison()
|
||||
{
|
||||
Lexer lexer = new ScaffoldLexer(new Token[]
|
||||
{
|
||||
new Token { type = Token.Type.NUMBER, data = 1f },
|
||||
new Token { type = Token.Type.LE },
|
||||
new Token { type = Token.Type.NUMBER, data = 2f },
|
||||
new Token { type = Token.Type.NE },
|
||||
new Token { type = Token.Type.NUMBER, data = 3f },
|
||||
});
|
||||
|
||||
IASTNode ast = new Parser(lexer).ParseExpression();
|
||||
|
||||
if (ast is ASTNodeComparison comp)
|
||||
{
|
||||
Assert.AreEqual(3, comp.nodes.Count);
|
||||
Assert.AreEqual(2, comp.comparisons.Count);
|
||||
Assert.IsInstanceOfType(comp.nodes[0], typeof(ASTNodeLiteral));
|
||||
Assert.IsInstanceOfType(comp.nodes[1], typeof(ASTNodeLiteral));
|
||||
Assert.IsInstanceOfType(comp.nodes[2], typeof(ASTNodeLiteral));
|
||||
Assert.AreEqual(Token.Type.LE, comp.comparisons[0]);
|
||||
Assert.AreEqual(Token.Type.NE, comp.comparisons[1]);
|
||||
}
|
||||
else Assert.Fail();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestDivision()
|
||||
{
|
||||
Lexer lexer = new ScaffoldLexer(new Token[]
|
||||
{
|
||||
new Token { type = Token.Type.NUMBER, data = 1f },
|
||||
new Token { type = Token.Type.SLASH },
|
||||
new Token { type = Token.Type.NUMBER, data = 2f },
|
||||
});
|
||||
|
||||
IASTNode ast = new Parser(lexer).ParseExpression();
|
||||
|
||||
Assert.IsInstanceOfType(ast, typeof(ASTNodeDivide));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestMinus()
|
||||
{
|
||||
Lexer lexer = new ScaffoldLexer(new Token[]
|
||||
{
|
||||
new Token { type = Token.Type.MINUS },
|
||||
new Token { type = Token.Type.NUMBER, data = 2f },
|
||||
new Token { type = Token.Type.MINUS },
|
||||
new Token { type = Token.Type.NUMBER, data = 3f },
|
||||
});
|
||||
|
||||
IASTNode ast = new Parser(lexer).ParseExpression();
|
||||
|
||||
if (ast is ASTNodeSubtract sub)
|
||||
{
|
||||
Assert.IsInstanceOfType(sub.lhs, typeof(ASTNodeNegative));
|
||||
Assert.IsInstanceOfType(sub.rhs, typeof(ASTNodeLiteral));
|
||||
}
|
||||
else Assert.Fail();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestOrderOfOperations()
|
||||
{
|
||||
Lexer lexer = new ScaffoldLexer(new Token[]
|
||||
{
|
||||
new Token { type = Token.Type.NUMBER, data = 1f },
|
||||
new Token { type = Token.Type.PLUS },
|
||||
new Token { type = Token.Type.NUMBER, data = 2f },
|
||||
new Token { type = Token.Type.ASTERISK },
|
||||
new Token { type = Token.Type.NUMBER, data = 3f },
|
||||
});
|
||||
|
||||
IASTNode ast = new Parser(lexer).ParseExpression();
|
||||
|
||||
if (ast is ASTNodeAdd add)
|
||||
{
|
||||
Assert.IsInstanceOfType(add.lhs, typeof(ASTNodeLiteral));
|
||||
|
||||
if (add.rhs is ASTNodeMultiply mul)
|
||||
{
|
||||
Assert.IsInstanceOfType(mul.lhs, typeof(ASTNodeLiteral));
|
||||
Assert.IsInstanceOfType(mul.rhs, typeof(ASTNodeLiteral));
|
||||
}
|
||||
else Assert.Fail();
|
||||
}
|
||||
else Assert.Fail();
|
||||
|
||||
lexer = new ScaffoldLexer(new Token[]
|
||||
{
|
||||
new Token { type = Token.Type.NUMBER, data = 1f },
|
||||
new Token { type = Token.Type.ASTERISK },
|
||||
new Token { type = Token.Type.NUMBER, data = 2f },
|
||||
new Token { type = Token.Type.PLUS },
|
||||
new Token { type = Token.Type.NUMBER, data = 3f },
|
||||
});
|
||||
|
||||
ast = new Parser(lexer).ParseExpression();
|
||||
|
||||
if (ast is ASTNodeAdd add2)
|
||||
{
|
||||
Assert.IsInstanceOfType(add2.rhs, typeof(ASTNodeLiteral));
|
||||
|
||||
if (add2.lhs is ASTNodeMultiply mul)
|
||||
{
|
||||
Assert.IsInstanceOfType(mul.lhs, typeof(ASTNodeLiteral));
|
||||
Assert.IsInstanceOfType(mul.rhs, typeof(ASTNodeLiteral));
|
||||
}
|
||||
else Assert.Fail();
|
||||
}
|
||||
else Assert.Fail();
|
||||
}
|
||||
}
|
||||
}
|
27
ShintenScriptTest/ScaffoldLexer.cs
Normal file
27
ShintenScriptTest/ScaffoldLexer.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
using ShintenScript;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ShintenScriptTest
|
||||
{
|
||||
class ScaffoldLexer : Lexer
|
||||
{
|
||||
Queue<Token> tokenQueue;
|
||||
|
||||
public ScaffoldLexer(IEnumerable<Token> queue) : base("")
|
||||
{
|
||||
tokenQueue = new Queue<Token>(queue);
|
||||
}
|
||||
|
||||
public override Token ParseOne()
|
||||
{
|
||||
if (tokenQueue.Count == 0)
|
||||
return new Token { type = Token.Type.EOF };
|
||||
|
||||
return tokenQueue.Dequeue();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -49,8 +49,11 @@
|
|||
<Reference Include="System.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="EvaluationTest.cs" />
|
||||
<Compile Include="LexerTests.cs" />
|
||||
<Compile Include="ParserTest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ScaffoldLexer.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue