mirror of
https://github.com/Cekis/SWG-ScriptConverter.git
synced 2026-09-27 12:13:37 -04:00
Add code
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using ScriptConverter.Ast.Statements;
|
||||
|
||||
namespace ScriptConverter.Parser.Parselets.Statements
|
||||
{
|
||||
class BlockParselet : IStatementParselet
|
||||
{
|
||||
public Statement Parse(ScriptParser parser, ScriptToken token, out bool trailingSemicolon)
|
||||
{
|
||||
trailingSemicolon = false;
|
||||
|
||||
var statements = new List<Statement>();
|
||||
|
||||
while (!parser.Match(ScriptTokenType.RightBrace))
|
||||
{
|
||||
statements.Add(parser.ParseStatement());
|
||||
}
|
||||
|
||||
parser.Take(ScriptTokenType.RightBrace);
|
||||
|
||||
return new BlockStatement(token, parser.Previous, statements);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using ScriptConverter.Ast.Statements;
|
||||
|
||||
namespace ScriptConverter.Parser.Parselets.Statements
|
||||
{
|
||||
class BreakParselet : IStatementParselet
|
||||
{
|
||||
public Statement Parse(ScriptParser parser, ScriptToken token, out bool trailingSemicolon)
|
||||
{
|
||||
trailingSemicolon = true;
|
||||
return new BreakStatement(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System.Collections.Generic;
|
||||
using ScriptConverter.Ast;
|
||||
using ScriptConverter.Ast.Statements;
|
||||
|
||||
namespace ScriptConverter.Parser.Parselets.Statements
|
||||
{
|
||||
class ConstVariableParselet : IStatementParselet
|
||||
{
|
||||
public Statement Parse(ScriptParser parser, ScriptToken token, out bool trailingSemicolon)
|
||||
{
|
||||
trailingSemicolon = true;
|
||||
|
||||
ScriptType type;
|
||||
string name;
|
||||
parser.ParseNamedType(out type, out name);
|
||||
|
||||
parser.Take(ScriptTokenType.Assign);
|
||||
|
||||
var value = parser.ParseExpression();
|
||||
|
||||
var definitions = new List<VariableStatement.Definition>()
|
||||
{
|
||||
new VariableStatement.Definition(type, name, value)
|
||||
};
|
||||
|
||||
return new VariableStatement(token, parser.Previous, type, true, definitions);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using ScriptConverter.Ast.Statements;
|
||||
|
||||
namespace ScriptConverter.Parser.Parselets.Statements
|
||||
{
|
||||
class ContinueParselet : IStatementParselet
|
||||
{
|
||||
public Statement Parse(ScriptParser parser, ScriptToken token, out bool trailingSemicolon)
|
||||
{
|
||||
trailingSemicolon = true;
|
||||
return new ContinueStatement(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using ScriptConverter.Ast.Statements;
|
||||
|
||||
namespace ScriptConverter.Parser.Parselets.Statements
|
||||
{
|
||||
class DoParselet : IStatementParselet
|
||||
{
|
||||
public Statement Parse(ScriptParser parser, ScriptToken token, out bool trailingSemicolon)
|
||||
{
|
||||
trailingSemicolon = true;
|
||||
|
||||
var block = parser.ParseBlock();
|
||||
|
||||
parser.Take(ScriptTokenType.While);
|
||||
parser.Take(ScriptTokenType.LeftParen);
|
||||
|
||||
var condition = parser.ParseExpression();
|
||||
|
||||
parser.Take(ScriptTokenType.RightParen);
|
||||
|
||||
return new DoStatement(token, parser.Previous, condition, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using ScriptConverter.Ast.Statements;
|
||||
|
||||
namespace ScriptConverter.Parser.Parselets.Statements
|
||||
{
|
||||
class EmptyParselet : IStatementParselet
|
||||
{
|
||||
public Statement Parse(ScriptParser parser, ScriptToken token, out bool trailingSemicolon)
|
||||
{
|
||||
trailingSemicolon = false;
|
||||
return new EmptyStatement(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ScriptConverter.Ast.Expressions;
|
||||
using ScriptConverter.Ast.Statements;
|
||||
|
||||
namespace ScriptConverter.Parser.Parselets.Statements
|
||||
{
|
||||
class ForParselet : IStatementParselet
|
||||
{
|
||||
public Statement Parse(ScriptParser parser, ScriptToken token, out bool trailingSemicolon)
|
||||
{
|
||||
trailingSemicolon = false;
|
||||
|
||||
parser.Take(ScriptTokenType.LeftParen);
|
||||
|
||||
List<Statement> initializers = null;
|
||||
if (!parser.Match(ScriptTokenType.Semicolon))
|
||||
{
|
||||
initializers = parser.ParseSeparatedBy(ScriptTokenType.Comma, (_, first) =>
|
||||
{
|
||||
var stmt = parser.ParseStatement(false);
|
||||
|
||||
if (!(stmt is VariableStatement) && !(stmt is NakedStatement))
|
||||
throw new CompilerException(token, "bad for loop initializer");
|
||||
|
||||
return stmt;
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
parser.Take(ScriptTokenType.Semicolon);
|
||||
|
||||
Expression condition = null;
|
||||
if (!parser.Match(ScriptTokenType.Semicolon))
|
||||
condition = parser.ParseExpression();
|
||||
|
||||
parser.Take(ScriptTokenType.Semicolon);
|
||||
|
||||
List<Expression> increment = null;
|
||||
if (!parser.Match(ScriptTokenType.RightParen))
|
||||
increment = parser.ParseSeparatedBy(ScriptTokenType.Comma, (_, first) => parser.ParseExpression()).ToList();
|
||||
|
||||
parser.Take(ScriptTokenType.RightParen);
|
||||
|
||||
var block = parser.ParseBlock();
|
||||
|
||||
return new ForStatement(token, parser.Previous, initializers, condition, increment, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System.Collections.Generic;
|
||||
using ScriptConverter.Ast.Expressions;
|
||||
using ScriptConverter.Ast.Statements;
|
||||
|
||||
namespace ScriptConverter.Parser.Parselets.Statements
|
||||
{
|
||||
class IfParselet : IStatementParselet
|
||||
{
|
||||
public Statement Parse(ScriptParser parser, ScriptToken token, out bool trailingSemicolon)
|
||||
{
|
||||
trailingSemicolon = false;
|
||||
|
||||
var first = true;
|
||||
var branches = new List<IfStatement.Branch>();
|
||||
IfStatement.Branch defaultBranch = null;
|
||||
|
||||
do
|
||||
{
|
||||
var isDefaultBranch = !first && !parser.MatchAndTake(ScriptTokenType.If);
|
||||
first = false;
|
||||
|
||||
Expression condition = null;
|
||||
if (!isDefaultBranch)
|
||||
{
|
||||
parser.Take(ScriptTokenType.LeftParen);
|
||||
|
||||
condition = parser.ParseExpression();
|
||||
|
||||
parser.Take(ScriptTokenType.RightParen);
|
||||
}
|
||||
|
||||
var block = parser.ParseBlock();
|
||||
var branch = new IfStatement.Branch(condition, block);
|
||||
|
||||
if (isDefaultBranch)
|
||||
defaultBranch = branch;
|
||||
else
|
||||
branches.Add(branch);
|
||||
|
||||
if (isDefaultBranch)
|
||||
break;
|
||||
} while (parser.MatchAndTake(ScriptTokenType.Else));
|
||||
|
||||
return new IfStatement(token, parser.Previous, branches, defaultBranch);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using ScriptConverter.Ast.Statements;
|
||||
|
||||
namespace ScriptConverter.Parser.Parselets.Statements
|
||||
{
|
||||
class ReturnParselet : IStatementParselet
|
||||
{
|
||||
public Statement Parse(ScriptParser parser, ScriptToken token, out bool trailingSemicolon)
|
||||
{
|
||||
trailingSemicolon = true;
|
||||
|
||||
if (parser.Match(ScriptTokenType.Semicolon))
|
||||
return new ReturnStatement(token, parser.Previous, null);
|
||||
|
||||
var value = parser.ParseExpression();
|
||||
return new ReturnStatement(token, parser.Previous, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.Collections.Generic;
|
||||
using ScriptConverter.Ast.Expressions;
|
||||
using ScriptConverter.Ast.Statements;
|
||||
|
||||
namespace ScriptConverter.Parser.Parselets.Statements
|
||||
{
|
||||
class SwitchParselet : IStatementParselet
|
||||
{
|
||||
public Statement Parse(ScriptParser parser, ScriptToken token, out bool trailingSemicolon)
|
||||
{
|
||||
trailingSemicolon = false;
|
||||
|
||||
parser.Take(ScriptTokenType.LeftParen);
|
||||
|
||||
var expression = parser.ParseExpression();
|
||||
|
||||
parser.Take(ScriptTokenType.RightParen);
|
||||
parser.Take(ScriptTokenType.LeftBrace);
|
||||
|
||||
var hasDefault = false;
|
||||
var branches = new List<SwitchStatement.Branch>();
|
||||
|
||||
while (!parser.Match(ScriptTokenType.RightBrace))
|
||||
{
|
||||
var conditions = new List<Expression>();
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (parser.MatchAndTake(ScriptTokenType.Case))
|
||||
{
|
||||
var condition = parser.ParseExpression();
|
||||
conditions.Add(condition);
|
||||
|
||||
parser.Take(ScriptTokenType.Colon);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!parser.Match(ScriptTokenType.Default))
|
||||
break;
|
||||
|
||||
var defaultToken = parser.Take(ScriptTokenType.Default);
|
||||
|
||||
if (hasDefault)
|
||||
throw new CompilerException(defaultToken, "Multiple default labels");
|
||||
|
||||
conditions.Add(null); // special default condition
|
||||
hasDefault = true;
|
||||
|
||||
parser.Take(ScriptTokenType.Colon);
|
||||
}
|
||||
|
||||
if (conditions.Count > 0)
|
||||
{
|
||||
var block = ParseBlock(parser);
|
||||
var branch = new SwitchStatement.Branch(conditions, block);
|
||||
branches.Add(branch);
|
||||
continue;
|
||||
}
|
||||
|
||||
var errorToken = parser.Peek();
|
||||
throw new CompilerException(errorToken, "Expected Case or Default but found {0}", errorToken);
|
||||
}
|
||||
|
||||
parser.Take(ScriptTokenType.RightBrace);
|
||||
|
||||
return new SwitchStatement(token, parser.Previous, expression, branches);
|
||||
}
|
||||
|
||||
private static BlockStatement ParseBlock(ScriptParser parser)
|
||||
{
|
||||
var statements = new List<Statement>();
|
||||
var start = parser.Peek();
|
||||
|
||||
while (!parser.Match(ScriptTokenType.Case) &&
|
||||
!parser.Match(ScriptTokenType.Default) &&
|
||||
!parser.Match(ScriptTokenType.RightBrace))
|
||||
{
|
||||
statements.Add(parser.ParseStatement());
|
||||
}
|
||||
|
||||
return new BlockStatement(start, parser.Previous, statements, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using ScriptConverter.Ast.Statements;
|
||||
|
||||
namespace ScriptConverter.Parser.Parselets.Statements
|
||||
{
|
||||
class ThrowParselet : IStatementParselet
|
||||
{
|
||||
public Statement Parse(ScriptParser parser, ScriptToken token, out bool trailingSemicolon)
|
||||
{
|
||||
trailingSemicolon = true;
|
||||
|
||||
var value = parser.ParseExpression();
|
||||
return new ThrowStatement(token, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.Collections.Generic;
|
||||
using ScriptConverter.Ast;
|
||||
using ScriptConverter.Ast.Statements;
|
||||
|
||||
namespace ScriptConverter.Parser.Parselets.Statements
|
||||
{
|
||||
class TryParselet : IStatementParselet
|
||||
{
|
||||
public Statement Parse(ScriptParser parser, ScriptToken token, out bool trailingSemicolon)
|
||||
{
|
||||
trailingSemicolon = false;
|
||||
|
||||
var mainBlock = parser.ParseBlock(false);
|
||||
var catches = new List<TryStatement.Branch>(2);
|
||||
|
||||
do
|
||||
{
|
||||
parser.Take(ScriptTokenType.Catch);
|
||||
parser.Take(ScriptTokenType.LeftParen);
|
||||
|
||||
ScriptType type;
|
||||
string name;
|
||||
parser.ParseNamedType(out type, out name);
|
||||
|
||||
parser.Take(ScriptTokenType.RightParen);
|
||||
|
||||
var block = parser.ParseBlock(false);
|
||||
catches.Add(new TryStatement.Branch(type, name, block));
|
||||
} while (parser.Match(ScriptTokenType.Catch));
|
||||
|
||||
return new TryStatement(token, parser.Previous, mainBlock, catches);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System.Linq;
|
||||
using ScriptConverter.Ast;
|
||||
using ScriptConverter.Ast.Expressions;
|
||||
using ScriptConverter.Ast.Statements;
|
||||
|
||||
namespace ScriptConverter.Parser.Parselets.Statements
|
||||
{
|
||||
class VariableParselet : IStatementParselet
|
||||
{
|
||||
public Statement Parse(ScriptParser parser, ScriptToken token, out bool trailingSemicolon)
|
||||
{
|
||||
trailingSemicolon = true;
|
||||
|
||||
var baseType = parser.ParseType(token);
|
||||
|
||||
var definitions = parser.ParseSeparatedBy(ScriptTokenType.Comma, (_, first) =>
|
||||
{
|
||||
var name = parser.Take(ScriptTokenType.Identifier).Contents;
|
||||
|
||||
var arrayDims = 0;
|
||||
while (parser.MatchAndTake(ScriptTokenType.LeftSquare))
|
||||
{
|
||||
parser.Take(ScriptTokenType.RightSquare);
|
||||
arrayDims++;
|
||||
}
|
||||
|
||||
var type = baseType;
|
||||
|
||||
if (arrayDims > 0)
|
||||
type = new ScriptType(baseType.Name, baseType.ArrayDimensions + arrayDims, baseType.IsResizable);
|
||||
|
||||
Expression value = null;
|
||||
if (parser.MatchAndTake(ScriptTokenType.Assign))
|
||||
value = parser.ParseExpression();
|
||||
|
||||
return new VariableStatement.Definition(type, name, value);
|
||||
}).ToList();
|
||||
|
||||
return new VariableStatement(token, parser.Previous, baseType, false, definitions);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using ScriptConverter.Ast.Statements;
|
||||
|
||||
namespace ScriptConverter.Parser.Parselets.Statements
|
||||
{
|
||||
class WhileParselet : IStatementParselet
|
||||
{
|
||||
public Statement Parse(ScriptParser parser, ScriptToken token, out bool trailingSemicolon)
|
||||
{
|
||||
trailingSemicolon = false;
|
||||
|
||||
parser.Take(ScriptTokenType.LeftParen);
|
||||
var condition = parser.ParseExpression();
|
||||
parser.Take(ScriptTokenType.RightParen);
|
||||
|
||||
var block = parser.ParseBlock();
|
||||
|
||||
return new WhileStatement(token, parser.Previous, condition, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user