progress
This commit is contained in:
parent
16e76d6b31
commit
484dbfc9d9
529 changed files with 113694 additions and 0 deletions
295
AspClassic.VBScript/Compiler/AnalysisScope.cs
Normal file
295
AspClassic.VBScript/Compiler/AnalysisScope.cs
Normal file
|
@ -0,0 +1,295 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using AspClassic.Scripting.Runtime;
|
||||
|
||||
using System.Dynamic;
|
||||
#if USE35
|
||||
using AspClassic.Scripting.Ast;
|
||||
#else
|
||||
using System.Linq.Expressions;
|
||||
#endif
|
||||
using AspClassic.Scripting.Utils;
|
||||
|
||||
namespace Dlrsoft.VBScript.Compiler
|
||||
{
|
||||
// AnalysisScope holds identifier information so that we can do name binding
|
||||
// during analysis. It manages a map from names to ParameterExprs so ET
|
||||
// definition locations and reference locations can alias the same variable.
|
||||
//
|
||||
// These chain from inner most BlockExprs, through LambdaExprs, to the root
|
||||
// which models a file or top-level expression. The root has non-None
|
||||
// ModuleExpr and RuntimeExpr, which are ParameterExprs.
|
||||
//
|
||||
internal class AnalysisScope
|
||||
{
|
||||
private AnalysisScope _parent;
|
||||
private string _name;
|
||||
// Need runtime for interning VBScript constants at code gen time.
|
||||
private VBScript _runtime;
|
||||
private ParameterExpression _runtimeParam;
|
||||
private ParameterExpression _moduleParam;
|
||||
private ParameterExpression _traceParam;
|
||||
private ISourceMapper _mapper;
|
||||
// Need IsLambda when support return to find tightest closing fun.
|
||||
private bool _isLambda = false;
|
||||
private bool _isLambdaBody = false;
|
||||
private bool _isDoLoop = false;
|
||||
private bool _isForLoop = false;
|
||||
private bool _isWith = false;
|
||||
private bool _isOptionExplicitOn = false;
|
||||
private bool _isOnErrorResumeNextOn = false;
|
||||
private LabelTarget _loopBreak = null;
|
||||
private LabelTarget _continueBreak = null;
|
||||
private LabelTarget _methodExit = null;
|
||||
private Dictionary<string, ParameterExpression> _names;
|
||||
private Set<string> _functionTable;
|
||||
private IList<VBScriptSyntaxError> _errors;
|
||||
private Expression _withExpression;
|
||||
private IDictionary<string, SymbolDocumentInfo> _docInfos;
|
||||
|
||||
public AnalysisScope(AnalysisScope parent, string name)
|
||||
: this(parent, name, null, null, null, null) { }
|
||||
|
||||
public AnalysisScope(AnalysisScope parent,
|
||||
string name,
|
||||
VBScript runtime,
|
||||
ParameterExpression runtimeParam,
|
||||
ParameterExpression moduleParam,
|
||||
ISourceMapper mapper)
|
||||
{
|
||||
_parent = parent;
|
||||
_name = name;
|
||||
_runtime = runtime;
|
||||
_runtimeParam = runtimeParam;
|
||||
_moduleParam = moduleParam;
|
||||
_mapper = mapper;
|
||||
|
||||
if (_moduleParam != null)
|
||||
{
|
||||
_functionTable = new Set<string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
_errors = new List<VBScriptSyntaxError>();
|
||||
_docInfos = new Dictionary<string, SymbolDocumentInfo>();
|
||||
}
|
||||
|
||||
_names = new Dictionary<string, ParameterExpression>();
|
||||
}
|
||||
|
||||
public AnalysisScope Parent { get { return _parent; } }
|
||||
|
||||
public ParameterExpression ModuleExpr { get { return _moduleParam; } }
|
||||
|
||||
public ParameterExpression RuntimeExpr { get { return _runtimeParam; } }
|
||||
|
||||
public VBScript Runtime { get { return _runtime; } }
|
||||
|
||||
public ISourceMapper SourceMapper { get { return _mapper; } }
|
||||
|
||||
public string Name { get { return _name; } }
|
||||
|
||||
public bool IsModule { get { return _moduleParam != null; } }
|
||||
|
||||
public bool IsOptionExplicitOn
|
||||
{
|
||||
get { return _isOptionExplicitOn; }
|
||||
set { _isOptionExplicitOn = value; }
|
||||
}
|
||||
|
||||
public bool IsOnErrorResumeNextOn
|
||||
{
|
||||
get { return _isOnErrorResumeNextOn; }
|
||||
set { _isOnErrorResumeNextOn = value; }
|
||||
}
|
||||
|
||||
public bool IsLambda
|
||||
{
|
||||
get { return _isLambda; }
|
||||
set { _isLambda = value; }
|
||||
}
|
||||
|
||||
|
||||
public bool IsLambdaBody
|
||||
{
|
||||
get { return _isLambdaBody; }
|
||||
set { _isLambdaBody = value; }
|
||||
}
|
||||
|
||||
public bool IsDoLoop
|
||||
{
|
||||
get { return _isDoLoop; }
|
||||
set { _isDoLoop = value; }
|
||||
}
|
||||
|
||||
public bool IsForLoop
|
||||
{
|
||||
get { return _isForLoop; }
|
||||
set { _isForLoop = value; }
|
||||
}
|
||||
|
||||
public bool IsWith
|
||||
{
|
||||
get { return _isWith; }
|
||||
set { _isWith = value; }
|
||||
}
|
||||
|
||||
public Expression WithExpression
|
||||
{
|
||||
get { return _withExpression; }
|
||||
set { _withExpression = value; }
|
||||
}
|
||||
|
||||
public Expression NearestWithExpression
|
||||
{
|
||||
get
|
||||
{
|
||||
var curScope = this;
|
||||
while (!curScope.IsWith && !curScope.IsLambdaBody && !curScope.IsModule) //With cannot across those boundaries
|
||||
{
|
||||
curScope = curScope.Parent;
|
||||
}
|
||||
return curScope.WithExpression;
|
||||
}
|
||||
}
|
||||
|
||||
public Expression ErrExpression
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.ModuleScope.Names[Dlrsoft.VBScript.VBScript.ERR_PARAMETER];
|
||||
}
|
||||
}
|
||||
|
||||
public Expression TraceExpression
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.ModuleScope.Names[Dlrsoft.VBScript.VBScript.TRACE_PARAMETER];
|
||||
}
|
||||
}
|
||||
|
||||
public LabelTarget LoopBreak
|
||||
{
|
||||
get { return _loopBreak; }
|
||||
set { _loopBreak = value; }
|
||||
}
|
||||
|
||||
public LabelTarget LoopContinue
|
||||
{
|
||||
get { return _continueBreak; }
|
||||
set { _continueBreak = value; }
|
||||
}
|
||||
|
||||
public LabelTarget MethodExit
|
||||
{
|
||||
get { return _methodExit; }
|
||||
set { _methodExit = value; }
|
||||
}
|
||||
|
||||
public Dictionary<string, ParameterExpression> Names
|
||||
{
|
||||
get { return _names; }
|
||||
set { _names = value; }
|
||||
}
|
||||
|
||||
public ParameterExpression GetModuleExpr()
|
||||
{
|
||||
var curScope = this;
|
||||
while (!curScope.IsModule)
|
||||
{
|
||||
curScope = curScope.Parent;
|
||||
}
|
||||
return curScope.ModuleExpr;
|
||||
}
|
||||
|
||||
|
||||
public AnalysisScope ModuleScope
|
||||
{
|
||||
get
|
||||
{
|
||||
var curScope = this;
|
||||
while (!curScope.IsModule)
|
||||
{
|
||||
curScope = curScope.Parent;
|
||||
}
|
||||
return curScope;
|
||||
}
|
||||
}
|
||||
|
||||
public AnalysisScope VariableScope
|
||||
{
|
||||
get
|
||||
{
|
||||
var curScope = this;
|
||||
while (!curScope.IsModule && !curScope.IsLambdaBody)
|
||||
{
|
||||
curScope = curScope.Parent;
|
||||
}
|
||||
return curScope;
|
||||
}
|
||||
}
|
||||
|
||||
public Set<string> FunctionTable
|
||||
{
|
||||
get
|
||||
{
|
||||
return ModuleScope._functionTable;
|
||||
}
|
||||
}
|
||||
|
||||
public IList<VBScriptSyntaxError> Errors
|
||||
{
|
||||
get { return _errors; }
|
||||
}
|
||||
|
||||
public VBScript GetRuntime()
|
||||
{
|
||||
var curScope = this;
|
||||
while (curScope.Runtime == null)
|
||||
{
|
||||
curScope = curScope.Parent;
|
||||
}
|
||||
return curScope.Runtime;
|
||||
}
|
||||
|
||||
//Can only call it on ModuleScope
|
||||
public SymbolDocumentInfo GetDocumentInfo(string path)
|
||||
{
|
||||
SymbolDocumentInfo docInfo;
|
||||
if (_docInfos.ContainsKey(path))
|
||||
{
|
||||
docInfo = _docInfos[path];
|
||||
}
|
||||
else
|
||||
{
|
||||
docInfo = Expression.SymbolDocument(path);
|
||||
_docInfos.Add(path, docInfo);
|
||||
}
|
||||
return docInfo;
|
||||
}
|
||||
|
||||
public void GetVariablesInScope(List<string> names, List<ParameterExpression> parameters)
|
||||
{
|
||||
AnalysisScope scope = this;
|
||||
while (!scope.IsModule)
|
||||
{
|
||||
foreach (string name in _names.Keys)
|
||||
{
|
||||
names.Add(name);
|
||||
parameters.Add(_names[name]);
|
||||
}
|
||||
scope = scope.Parent;
|
||||
}
|
||||
|
||||
//Now we are dealing with module scope. We want to exclude lambda variables
|
||||
Set<string> functionTable = FunctionTable;
|
||||
foreach (string name in _names.Keys)
|
||||
{
|
||||
if (!functionTable.Contains(name))
|
||||
{
|
||||
names.Add(name);
|
||||
parameters.Add(_names[name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} //AnalysisScope}
|
||||
}
|
19
AspClassic.VBScript/Compiler/DocSpan.cs
Normal file
19
AspClassic.VBScript/Compiler/DocSpan.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using AspClassic.Scripting;
|
||||
|
||||
namespace Dlrsoft.VBScript.Compiler
|
||||
{
|
||||
public class DocSpan
|
||||
{
|
||||
public DocSpan(string uri, SourceSpan span)
|
||||
{
|
||||
this.Uri = uri;
|
||||
this.Span = span;
|
||||
}
|
||||
|
||||
public string Uri { get; set; }
|
||||
public SourceSpan Span { get; set; }
|
||||
}
|
||||
}
|
12
AspClassic.VBScript/Compiler/ISourceMapper.cs
Normal file
12
AspClassic.VBScript/Compiler/ISourceMapper.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using AspClassic.Scripting;
|
||||
|
||||
namespace Dlrsoft.VBScript.Compiler
|
||||
{
|
||||
public interface ISourceMapper
|
||||
{
|
||||
DocSpan Map(SourceSpan span);
|
||||
}
|
||||
}
|
88
AspClassic.VBScript/Compiler/Set.cs
Normal file
88
AspClassic.VBScript/Compiler/Set.cs
Normal file
|
@ -0,0 +1,88 @@
|
|||
/* ****************************************************************************
|
||||
*
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* This source code is subject to terms and conditions of the Microsoft Public License. A
|
||||
* copy of the license can be found in the License.html file at the root of this distribution. If
|
||||
* you cannot locate the Microsoft Public License, please send an email to
|
||||
* dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
|
||||
* by the terms of the Microsoft Public License.
|
||||
*
|
||||
* You must not remove this notice, or any other, from this software.
|
||||
*
|
||||
*
|
||||
* ***************************************************************************/
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Dlrsoft.VBScript.Compiler {
|
||||
/// <summary>
|
||||
/// A simple hashset, built on Dictionary{K, V}
|
||||
/// </summary>
|
||||
internal sealed class Set<T> : ICollection<T> {
|
||||
private readonly Dictionary<T, object> _data;
|
||||
|
||||
internal Set() {
|
||||
_data = new Dictionary<T, object>();
|
||||
}
|
||||
|
||||
internal Set(IEqualityComparer<T> comparer) {
|
||||
_data = new Dictionary<T, object>(comparer);
|
||||
}
|
||||
|
||||
internal Set(IList<T> list) {
|
||||
_data = new Dictionary<T, object>(list.Count);
|
||||
foreach (T t in list) {
|
||||
Add(t);
|
||||
}
|
||||
}
|
||||
|
||||
internal Set(IEnumerable<T> list) {
|
||||
_data = new Dictionary<T, object>();
|
||||
foreach (T t in list) {
|
||||
Add(t);
|
||||
}
|
||||
}
|
||||
|
||||
internal Set(int capacity) {
|
||||
_data = new Dictionary<T, object>(capacity);
|
||||
}
|
||||
|
||||
public void Add(T item) {
|
||||
_data[item] = null;
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
_data.Clear();
|
||||
}
|
||||
|
||||
public bool Contains(T item) {
|
||||
return _data.ContainsKey(item);
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex) {
|
||||
_data.Keys.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public int Count {
|
||||
get { return _data.Count; }
|
||||
}
|
||||
|
||||
public bool IsReadOnly {
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public bool Remove(T item) {
|
||||
return _data.Remove(item);
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator() {
|
||||
return _data.Keys.GetEnumerator();
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
|
||||
return _data.Keys.GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
179
AspClassic.VBScript/Compiler/SourceUtil.cs
Normal file
179
AspClassic.VBScript/Compiler/SourceUtil.cs
Normal file
|
@ -0,0 +1,179 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using AspClassic.Scripting;
|
||||
|
||||
namespace Dlrsoft.VBScript.Compiler
|
||||
{
|
||||
public class SourceUtil
|
||||
{
|
||||
public static int GetLineCount(string source)
|
||||
{
|
||||
int lineCount = 0;
|
||||
if (string.IsNullOrEmpty(source))
|
||||
return lineCount;
|
||||
|
||||
int start = 0;
|
||||
int len = source.Length;
|
||||
while (start < len)
|
||||
{
|
||||
int pos = source.IndexOf('\r', start);
|
||||
if (pos > -1)
|
||||
{
|
||||
lineCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
start = pos + 1;
|
||||
if (start < len && source[start] == '\n')
|
||||
{
|
||||
start++;
|
||||
}
|
||||
}
|
||||
|
||||
//Last line with CR/LF
|
||||
//We got an empty line in this situation
|
||||
if (len >= start)
|
||||
{
|
||||
lineCount++;
|
||||
}
|
||||
|
||||
return lineCount;
|
||||
}
|
||||
|
||||
public static Range[] GetLineRanges(string source)
|
||||
{
|
||||
if (string.IsNullOrEmpty(source))
|
||||
return new Range[]{};
|
||||
|
||||
List<Range> lineRanges = new List<Range>();
|
||||
int start = 0;
|
||||
int len = source.Length;
|
||||
|
||||
while (start < len)
|
||||
{
|
||||
int pos = source.IndexOf('\r', start);
|
||||
if (pos < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (pos + 1 < len && source[pos + 1] == '\n')
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
|
||||
lineRanges.Add(new Range(start, pos));
|
||||
start = pos + 1;
|
||||
}
|
||||
|
||||
//Last line with CR/LF
|
||||
if (len > start)
|
||||
{
|
||||
lineRanges.Add(new Range(start, len-1));
|
||||
}
|
||||
|
||||
return lineRanges.ToArray();
|
||||
}
|
||||
|
||||
public static LineColumn GetLineColumn(Range[] lineRanges, int index)
|
||||
{
|
||||
IComparer comparer = new RangeComparer();
|
||||
int i = Array.BinarySearch(lineRanges, 0, lineRanges.Length, index, comparer);
|
||||
return new LineColumn(i + 1, index - lineRanges[i].Start + 1);
|
||||
}
|
||||
|
||||
public static SourceSpan GetSpan(Range[] lineRanges, int start, int end)
|
||||
{
|
||||
LineColumn lcStart = GetLineColumn(lineRanges, start);
|
||||
SourceLocation slStart = new SourceLocation(start, lcStart.Line, lcStart.Column);
|
||||
LineColumn lcEnd = GetLineColumn(lineRanges, end);
|
||||
SourceLocation slEnd = new SourceLocation(end, lcEnd.Line, lcEnd.Column);
|
||||
return new SourceSpan(slStart, slEnd);
|
||||
}
|
||||
|
||||
internal static SourceSpan ConvertSpan(AspClassic.Parser.Span span)
|
||||
{
|
||||
AspClassic.Parser.Location start = span.Start;
|
||||
AspClassic.Parser.Location end = span.Finish;
|
||||
return new SourceSpan(
|
||||
new SourceLocation(start.Index, start.Line, start.Column),
|
||||
new SourceLocation(end.Index, end.Line, end.Column)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public struct Range
|
||||
{
|
||||
public int Start;
|
||||
public int End;
|
||||
|
||||
public Range(int start, int end)
|
||||
{
|
||||
this.Start = start;
|
||||
this.End = end;
|
||||
}
|
||||
}
|
||||
|
||||
public struct LineColumn
|
||||
{
|
||||
public int Line;
|
||||
public int Column;
|
||||
|
||||
public LineColumn(int line, int column)
|
||||
{
|
||||
this.Line = line;
|
||||
this.Column = column;
|
||||
}
|
||||
}
|
||||
|
||||
internal class RangeComparer : IComparer
|
||||
{
|
||||
#region IComparer Members
|
||||
|
||||
public int Compare(object range, object index)
|
||||
{
|
||||
Range theRange = (Range)range;
|
||||
int theIndex = (int)index;
|
||||
|
||||
if (theRange.End < theIndex)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (theRange.Start > theIndex)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
internal class SpanComparer : IComparer<SourceSpan>
|
||||
{
|
||||
#region IComparer Members
|
||||
|
||||
public int Compare(SourceSpan x, SourceSpan y)
|
||||
{
|
||||
if (x.End.Line < y.Start.Line)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (x.Start.Line > y.End.Line)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
136
AspClassic.VBScript/Compiler/VBScriptAnalyzer.cs
Normal file
136
AspClassic.VBScript/Compiler/VBScriptAnalyzer.cs
Normal file
|
@ -0,0 +1,136 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using VB = AspClassic.Parser;
|
||||
using AspClassic.Scripting.Runtime;
|
||||
|
||||
using System.Dynamic;
|
||||
#if USE35
|
||||
using AspClassic.Scripting.Ast;
|
||||
#else
|
||||
using System.Linq.Expressions;
|
||||
#endif
|
||||
|
||||
using AspClassic.Scripting.Utils;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using Dlrsoft.VBScript.Binders;
|
||||
using Dlrsoft.VBScript.Compiler;
|
||||
using Dlrsoft.VBScript.Runtime;
|
||||
using Debug = System.Diagnostics.Debug;
|
||||
|
||||
namespace Dlrsoft.VBScript.Compiler
|
||||
{
|
||||
/// <summary>
|
||||
/// The analysis phase. We don't do much except for generating the global functions, constants and variables table
|
||||
/// </summary>
|
||||
internal class VBScriptAnalyzer
|
||||
{
|
||||
public static void AnalyzeFile(AspClassic.Parser.ScriptBlock block, AnalysisScope scope)
|
||||
{
|
||||
Debug.Assert(scope.IsModule);
|
||||
|
||||
if (block.Statements != null)
|
||||
{
|
||||
foreach (VB.Statement s in block.Statements)
|
||||
{
|
||||
AnalyzeStatement(s, scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AnalyzeStatement(VB.Statement s, AnalysisScope scope)
|
||||
{
|
||||
if (s is VB.MethodDeclaration)
|
||||
{
|
||||
string methodName = ((VB.MethodDeclaration)s).Name.Name.ToLower();
|
||||
scope.FunctionTable.Add(methodName);
|
||||
ParameterExpression method = Expression.Parameter(typeof(object));
|
||||
scope.Names[methodName] = method;
|
||||
}
|
||||
else if (s is VB.LocalDeclarationStatement)
|
||||
{
|
||||
AnalyzeDeclarationExpr((VB.LocalDeclarationStatement)s, scope);
|
||||
}
|
||||
else if (s is VB.IfBlockStatement)
|
||||
{
|
||||
AnalyzeIfBlockStatement((VB.IfBlockStatement)s, scope);
|
||||
}
|
||||
else if (s is VB.SelectBlockStatement)
|
||||
{
|
||||
AnalyzeSelectBlockStatement((VB.SelectBlockStatement)s, scope);
|
||||
}
|
||||
else if (s is VB.BlockStatement)
|
||||
{
|
||||
AnalyzeBlockStatement((VB.BlockStatement)s, scope);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AnalyzeDeclarationExpr(VB.LocalDeclarationStatement stmt, AnalysisScope scope)
|
||||
{
|
||||
bool isConst = false;
|
||||
|
||||
if (stmt.Modifiers != null)
|
||||
{
|
||||
if (stmt.Modifiers.ModifierTypes == VB.ModifierTypes.Const)
|
||||
{
|
||||
isConst = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (VB.VariableDeclarator d in stmt.VariableDeclarators)
|
||||
{
|
||||
foreach (VB.VariableName v in d.VariableNames)
|
||||
{
|
||||
string name = v.Name.Name.ToLower();
|
||||
|
||||
ParameterExpression p = Expression.Parameter(typeof(object), name);
|
||||
scope.Names.Add(name, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AnalyzeIfBlockStatement(VB.IfBlockStatement block, AnalysisScope scope)
|
||||
{
|
||||
AnalyzeBlockStatement(block, scope);
|
||||
if (block.ElseIfBlockStatements != null && block.ElseIfBlockStatements.Count > 0)
|
||||
{
|
||||
foreach (VB.ElseIfBlockStatement elseif in block.ElseIfBlockStatements)
|
||||
{
|
||||
AnalyzeBlockStatement(elseif, scope);
|
||||
}
|
||||
}
|
||||
if (block.ElseBlockStatement != null)
|
||||
{
|
||||
AnalyzeBlockStatement(block.ElseBlockStatement, scope);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AnalyzeSelectBlockStatement(VB.SelectBlockStatement block, AnalysisScope scope)
|
||||
{
|
||||
AnalyzeBlockStatement(block, scope);
|
||||
if (block.CaseBlockStatements != null && block.CaseBlockStatements.Count > 0)
|
||||
{
|
||||
foreach (VB.CaseBlockStatement caseStmt in block.CaseBlockStatements)
|
||||
{
|
||||
AnalyzeBlockStatement(caseStmt, scope);
|
||||
}
|
||||
}
|
||||
if (block.CaseElseBlockStatement != null)
|
||||
{
|
||||
AnalyzeBlockStatement(block.CaseElseBlockStatement, scope);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AnalyzeBlockStatement(VB.BlockStatement block, AnalysisScope scope)
|
||||
{
|
||||
if (block.Statements != null)
|
||||
{
|
||||
foreach (VB.Statement stmt in block.Statements)
|
||||
{
|
||||
AnalyzeStatement(stmt, scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
21
AspClassic.VBScript/Compiler/VBScriptCompilerException.cs
Normal file
21
AspClassic.VBScript/Compiler/VBScriptCompilerException.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Dlrsoft.VBScript.Compiler
|
||||
{
|
||||
public class VBScriptCompilerException : Exception
|
||||
{
|
||||
private IList<VBScriptSyntaxError> _errors;
|
||||
|
||||
public VBScriptCompilerException(IList<VBScriptSyntaxError> errors)
|
||||
{
|
||||
_errors = errors;
|
||||
}
|
||||
|
||||
public IList<VBScriptSyntaxError> SyntaxErrors
|
||||
{
|
||||
get { return _errors; }
|
||||
}
|
||||
}
|
||||
}
|
1844
AspClassic.VBScript/Compiler/VBScriptGenerator.cs
Normal file
1844
AspClassic.VBScript/Compiler/VBScriptGenerator.cs
Normal file
File diff suppressed because it is too large
Load diff
24
AspClassic.VBScript/Compiler/VBScriptSourceCodeReader.cs
Normal file
24
AspClassic.VBScript/Compiler/VBScriptSourceCodeReader.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using AspClassic.Scripting;
|
||||
|
||||
namespace Dlrsoft.VBScript.Compiler
|
||||
{
|
||||
public class VBScriptSourceCodeReader : SourceCodeReader
|
||||
{
|
||||
private ISourceMapper _mapper;
|
||||
|
||||
public VBScriptSourceCodeReader(TextReader textReader, Encoding encoding, ISourceMapper mapper)
|
||||
: base(textReader, encoding)
|
||||
{
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
public ISourceMapper SourceMapper
|
||||
{
|
||||
get { return _mapper; }
|
||||
}
|
||||
}
|
||||
}
|
66
AspClassic.VBScript/Compiler/VBScriptSourceMapper.cs
Normal file
66
AspClassic.VBScript/Compiler/VBScriptSourceMapper.cs
Normal file
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using AspClassic.Scripting;
|
||||
using System.Text;
|
||||
|
||||
namespace Dlrsoft.VBScript.Compiler
|
||||
{
|
||||
public class VBScriptSourceMapper : ISourceMapper
|
||||
{
|
||||
//Here the range is start line number and the end line number
|
||||
private List<SourceSpan> _spans = new List<SourceSpan>(); //use ArrayList so that we can use the binary search method
|
||||
private IDictionary<SourceSpan, DocSpan> _mappings = new Dictionary<SourceSpan, DocSpan>();
|
||||
static private SpanComparer _comparer = new SpanComparer();
|
||||
|
||||
public VBScriptSourceMapper() {}
|
||||
|
||||
public void AddMapping(SourceSpan generatedSpan, DocSpan span)
|
||||
{
|
||||
_spans.Add(generatedSpan);
|
||||
_mappings[generatedSpan] = span;
|
||||
}
|
||||
|
||||
#region ISourceMapper Members
|
||||
|
||||
public DocSpan Map(SourceSpan span)
|
||||
{
|
||||
int generatedStartLine = span.Start.Line;
|
||||
int index = _spans.BinarySearch(span, _comparer);
|
||||
SourceSpan containingSpan = (SourceSpan)_spans[index];
|
||||
DocSpan docSpan = _mappings[containingSpan];
|
||||
|
||||
int rawStartIndex = docSpan.Span.Start.Index + span.Start.Index - containingSpan.Start.Index;
|
||||
int lineOffSet = generatedStartLine - containingSpan.Start.Line;
|
||||
int rawStartLine = docSpan.Span.Start.Line + lineOffSet;
|
||||
int rawStartColumn;
|
||||
if (lineOffSet == 0)
|
||||
{
|
||||
rawStartColumn = docSpan.Span.Start.Column + span.Start.Column;
|
||||
}
|
||||
else
|
||||
{
|
||||
rawStartColumn = span.Start.Column;
|
||||
}
|
||||
int lines = span.End.Line - generatedStartLine;
|
||||
int rawEndIndex = rawStartIndex + span.End.Index + span.Start.Index;
|
||||
int rawEndLine = rawStartLine + lines;
|
||||
int rawEndColumn;
|
||||
if (lines == 0)
|
||||
{
|
||||
rawEndColumn = rawStartColumn + span.End.Column - span.Start.Column;
|
||||
}
|
||||
else
|
||||
{
|
||||
rawEndColumn = span.End.Column;
|
||||
}
|
||||
return new DocSpan(docSpan.Uri,
|
||||
new SourceSpan(
|
||||
new SourceLocation(rawStartIndex, rawStartLine, rawStartColumn),
|
||||
new SourceLocation(rawEndIndex, rawEndLine, rawEndColumn)
|
||||
)
|
||||
);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Dynamic;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using AspClassic.Scripting;
|
||||
using AspClassic.Scripting.Utils;
|
||||
|
||||
namespace Dlrsoft.VBScript.Compiler
|
||||
{
|
||||
public class VBScriptStringContentProvider : TextContentProvider {
|
||||
private readonly string _code;
|
||||
private ISourceMapper _mapper;
|
||||
|
||||
public VBScriptStringContentProvider(string code, ISourceMapper mapper)
|
||||
{
|
||||
ContractUtils.RequiresNotNull(code, "code");
|
||||
|
||||
_code = code;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
public override SourceCodeReader GetReader() {
|
||||
return new VBScriptSourceCodeReader(new StringReader(_code), null, _mapper);
|
||||
}
|
||||
}
|
||||
}
|
23
AspClassic.VBScript/Compiler/VBScriptSyntaxError.cs
Normal file
23
AspClassic.VBScript/Compiler/VBScriptSyntaxError.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using AspClassic.Scripting;
|
||||
|
||||
namespace Dlrsoft.VBScript.Compiler
|
||||
{
|
||||
public class VBScriptSyntaxError
|
||||
{
|
||||
public VBScriptSyntaxError(string fileName, SourceSpan span, int errCode, string errorDesc)
|
||||
{
|
||||
this.FileName = fileName;
|
||||
this.Span = span;
|
||||
this.ErrorCode = errCode;
|
||||
this.ErrorDescription = errorDesc;
|
||||
}
|
||||
|
||||
public string FileName { get; set; }
|
||||
public SourceSpan Span { get; set; }
|
||||
public int ErrorCode { get; set; }
|
||||
public string ErrorDescription { get; set; }
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue