pascalabcnet/ParserTools/ParserTools/SourceContextMap.cs
Mikhalkovich Stanislav e603b1fd6d Mikhalkovich в Copyright
Заготовка для школьного плагина образцов кода
2019-07-28 23:53:15 +03:00

100 lines
3.8 KiB
C#

// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Text;
using PascalABCCompiler.SyntaxTree;
namespace PascalABCCompiler.ParserTools
{
public class SourceContextComparer : IComparer<SourceContext>
{
public int Compare(SourceContext x, SourceContext y)
{
return x.Position - y.Position;
}
}
public class SourceContextPair
{
SourceContext NewContext;
SourceContext RealContext;
public SourceContextPair(SourceContext x, SourceContext y)
{
NewContext = x;
RealContext = y;
}
public SourceContext GetNew()
{
return NewContext;
}
public SourceContext GetReal()
{
return RealContext;
}
}
public class SourceContextMap
{
SourceContext CurrentSourceContext = null;
//SortedList<SourceContext, SourceContext> AreaList = new SortedList<SourceContext, SourceContext>(new SourceContextComparer());
List<SourceContextPair> AreaList = new List<SourceContextPair>();
SourceContext Find(SourceContext tf)
{
//TODO Надо сделать половинным делением
//foreach (SourceContext t in AreaList.Keys)
// if (tf.In(t))
// return t;
//return null;
if (AreaList.Count == 0)
return null;
if ( tf.begin_position.line_num < 1 || tf.begin_position.line_num > AreaList.Count)
return AreaList[AreaList.Count-1].GetNew();
else
return AreaList[tf.begin_position.line_num - 1].GetNew();
//return AreaList.Keys[tf.begin_position.line_num - 1];
}
public void AddArea(SourceContext tf, SourceContext real_context)
{
AreaList.Add(new SourceContextPair(tf, real_context));
//AreaList.Add(tf, real_context);
}
public SourceContext GetSourceContext(SourceContext scv)
{
//Это надо считать только по мере надобности!!!
SourceContext scvf;
if (CurrentSourceContext != null && scv.In(CurrentSourceContext))
scvf = CurrentSourceContext;
else
{
scvf = Find(scv);
CurrentSourceContext = scvf;
}
//scvf = Find(scv);
if (scvf == null)
return scv;
//SourceContext sco = AreaList[scvf];
if (scvf.begin_position.line_num < 1 || scvf.begin_position.line_num > AreaList.Count)
return null;
SourceContext sco = AreaList[scvf.begin_position.line_num - 1].GetReal();
SourceContext scn = new SourceContext(
sco.begin_position.line_num + scv.begin_position.line_num - scvf.begin_position.line_num,
sco.begin_position.column_num + scv.begin_position.column_num - scvf.begin_position.column_num,
//sco.begin_position.column_num == -1 ? 1 : scv.begin_position.column_num,
sco.end_position.line_num + scv.end_position.line_num - scvf.end_position.line_num,
sco.begin_position.column_num + scv.end_position.column_num - 1,
//sco.end_position.column_num == -1 ? 1 : scv.end_position.column_num,
sco.Position + scv.Position - scvf.Position,
sco.Position + scv.Position - scvf.Position + scv.Length);
scn.FileName = sco.FileName;
return scn;
}
}
}