LightSymInfo rework (#2994)

* LightSymInfo rework

* add rebuildDebug and build units

* enable VarNamesInMethodsWithSameNameAsClassGenericParamsReplacer

* remove CollectFullLightSymInfo call

* fix

fix

remove CollectFullLightSymInfo call
This commit is contained in:
nevermind322 2023-12-31 12:54:49 +03:00 committed by GitHub
parent 8193bc730f
commit a8b1e9035b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 623 additions and 323 deletions

View file

@ -21,12 +21,11 @@ namespace PascalABCCompiler.SyntaxTreeConverters
// FillParentNodeVisitor расположен в SyntaxTree/tree как базовый визитор, отвечающий за построение дерева
//FillParentNodeVisitor.New.ProcessNode(root); // почему-то перепрошивает не всё. А следующий вызов - всё
root.FillParentsInAllChilds();
#if DEBUG
// var stat = new ABCStatisticsVisitor();
// stat.ProcessNode(root);
// var stat = new ABCStatisticsVisitor();
// stat.ProcessNode(root);
#endif
// new range - до всего! До выноса выражения с лямбдой из foreach. 11.07 добавил поиск yields и присваивание pd.HasYield
NewRangeDesugarAndFindHasYieldVisitor.New.ProcessNode(root);
@ -38,7 +37,7 @@ namespace PascalABCCompiler.SyntaxTreeConverters
// Выносим выражения с лямбдами из заголовка foreach + считаем максимум 10 вложенных лямбд
StandOutExprWithLambdaInForeachSequenceAndNestedLambdasVisitor.New.ProcessNode(root);
VarNamesInMethodsWithSameNameAsClassGenericParamsReplacer.New.ProcessNode(root); // SSM bug fix #1147
new VarNamesInMethodsWithSameNameAsClassGenericParamsReplacer(root as compilation_unit).ProcessNode(root);
FindOnExceptVarsAndApplyRenameVisitor.New.ProcessNode(root);
// loop
@ -54,13 +53,13 @@ namespace PascalABCCompiler.SyntaxTreeConverters
IndexVisitor.New.ProcessNode(root);
// slice_expr и slice_expr_question
SliceDesugarVisitor.New.ProcessNode(root);
SliceDesugarVisitor.New.ProcessNode(root);
// поставил раньше AssignTuplesDesugarVisitor из за var (a,b) := a[1:3];
// теперь коллизия с (a[1:6], a[6:11]):= (a[6:11], a[1:6]);
// assign_tuple и assign_var_tuple
AssignTuplesDesugarVisitor.New.ProcessNode(root); // теперь это - на семантике
// question_point_desugar_visitor
QuestionPointDesugarVisitor.New.ProcessNode(root);

View file

@ -0,0 +1,71 @@

namespace PascalABCCompiler.SyntaxTree
{
public class BindCollectLightSymInfo : CollectLightSymInfoVisitor
{
protected override AbstractScopeCreator scopeCreator => _scopeCreator;
private CachingScopeCreator _scopeCreator = new CachingScopeCreator();
public BindCollectLightSymInfo(compilation_unit root) : base(root)
{
Current = Root;
visit(root);
}
public SymInfoSyntax bind(ident node)
{
///Console.WriteLine("searching " + node.ToString());
syntax_tree_node cur_node = node;
while (cur_node != null)
{
// Console.WriteLine("cur_node: " + cur_node.ToString());
if (AbstractScopeCreator.IsScopeCreator(cur_node))
{
//Console.WriteLine("checking scope" + cur_node.ToString())
var cur_scope = scopeCreator.GetScope(cur_node);
//Console.WriteLine(cur_scope.ToString() + ": " + cur_scope.Symbols.Count);
var prev_scope = Current;
if (prev_scope != null)
prev_scope.Parent = cur_scope;
Current = cur_scope;
if (cur_scope.Parent == null && !(Current is GlobalScopeSyntax))
{
//Console.WriteLine("visiting " + cur_node.ToString());
cur_node.visit(this);
}
var res = Current.bind(node);
if (res != null) return res;
}
cur_node = cur_node.Parent;
}
return null;
}
public override void Enter(syntax_tree_node st)
{
if (AbstractScopeCreator.IsScopeCreator(st))
{
if (st is procedure_definition pd)
{
var attr = pd.proc_header.class_keyword ? SymbolAttributes.class_attr : 0;
var name = pd.proc_header?.name?.meth_name;
if (name != null)
if (pd.proc_header is function_header)
Current.AddSymbol(name, SymKind.funcname, null, attr);
else
Current.AddSymbol(name, SymKind.procname, null, attr);
}
visitNode = false;
}
}
public override void PreExitScope(syntax_tree_node st){}
}
}

View file

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PascalABCCompiler.SyntaxTree
{
public class CollectFullLightSymInfoVisitor : CollectLightSymInfoVisitor
{
protected override AbstractScopeCreator scopeCreator => _scopeCreator;
private CachingScopeCreator _scopeCreator = new CachingScopeCreator();
public CollectFullLightSymInfoVisitor(compilation_unit root) : base(root)
{
}
public override void Enter(syntax_tree_node st)
{
var scope = scopeCreator.GetScope(st);
if (scope != null)
{
scope.Parent = Current;
Current = scope;
}
}
public override void Exit(syntax_tree_node st)
{
if (AbstractScopeCreator.IsScopeCreator(st))
{
PreExitScope(st);
if (Current != null)
Current = Current.Parent;
}
}
public override void visit(procedure_definition node)
{
var name = node.proc_header?.name?.meth_name;
var attr = node.proc_header.class_keyword ? SymbolAttributes.class_attr : 0;
if (name != null)
if (node.proc_header is function_header)
Current.Parent.AddSymbol(name, SymKind.funcname, null, attr);
else
Current.Parent.AddSymbol(name, SymKind.procname, null, attr);
base.visit(node);
}
public override void PreExitScope(syntax_tree_node st)
{
}
}
}

View file

@ -0,0 +1,211 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace PascalABCCompiler.SyntaxTree
{
public abstract class CollectLightSymInfoVisitor : BaseEnterExitVisitor
{
public GlobalScopeSyntax Root;
public ScopeSyntax Current;
protected Dictionary<string, NamedScopeSyntax> classes = new Dictionary<string, NamedScopeSyntax>();
protected bool inPrivate = false;
public CollectLightSymInfoVisitor(compilation_unit root)
{
Root = scopeCreator.GetScope(root) as GlobalScopeSyntax;
}
abstract protected AbstractScopeCreator scopeCreator
{ get; }
public ScopeSyntax GetScope(syntax_tree_node node) => scopeCreator.GetScope(node);
public abstract void PreExitScope(syntax_tree_node st);
public override void visit(var_def_statement vd)
{
var attr = vd.var_attr == definition_attribute.Static ? SymbolAttributes.class_attr : 0;
if (vd == null || vd.vars == null || vd.vars.list == null)
return;
AddSymbols(vd.vars.list, SymKind.var, vd.vars_type, attr);
base.visit(vd);
}
public override void visit(formal_parameters fp)
{
foreach (var pg in fp.params_list)
{
if (pg.param_kind == parametr_kind.var_parametr)
AddSymbols(pg.idents.idents, SymKind.param, null, SymbolAttributes.varparam_attr);
else
AddSymbols(pg.idents.idents, SymKind.param);
}
base.visit(fp);
}
public override void visit (simple_const_definition node)
{
AddSymbol(node.const_name, SymKind.const_var);
}
public override void visit(type_declaration td)
{
if (td.type_def is class_definition cd)
{
var tname = td.type_name;
if (cd.keyword == class_keyword.Class || cd.keyword == class_keyword.TemplateClass)
AddSymbol(tname, SymKind.classname);
else if (cd.keyword == class_keyword.Record || cd.keyword == class_keyword.TemplateRecord)
AddSymbol(tname, SymKind.recordname);
else if (cd.keyword == class_keyword.Interface || cd.keyword == class_keyword.TemplateInterface)
AddSymbol(tname, SymKind.interfacename);
if (!classes.ContainsKey(td.type_name.name))
{
classes.Add(td.type_name.name, scopeCreator.GetScope(td.type_def) as NamedScopeSyntax);
//Console.WriteLine("Added" + td.type_name.name + " " + (scopeCreator.GetScope(td.type_def) as ClassScopeSyntax));
}
}
else if (td.type_def is named_type_reference)
{
AddSymbol(td.type_name, SymKind.type_alias);
}
base.visit(td);
}
public override void visit(class_members cm)
{
if (cm.access_mod.access_level == access_modifer.private_modifer)
{
inPrivate = true;
}
base.visit(cm);
inPrivate = false;
}
public override void visit(for_node f)
{
if (f.create_loop_variable || f.type_name != null)
AddSymbol(f.loop_variable, SymKind.var, f.type_name);
base.visit(f);
}
public override void visit(procedure_definition node)
{
var name = node.proc_header?.name?.meth_name;
var attr = node.proc_header.class_keyword ? SymbolAttributes.class_attr : 0;
if (name != null)
if (node.proc_header?.name?.class_name != null)
{
var class_name = node.proc_header.name.class_name.name;
if (classes.ContainsKey(class_name))
{
(Current as ProcScopeSyntax).classParent = classes[class_name];
(Current as ProcScopeSyntax).classParent.AddSymbol(name, SymKind.funcname, null, attr);
}
}
base.visit(node);
}
public override void visit(class_definition cd)
{
var classScope = Current as NamedScopeSyntax;
if (cd.class_parents != null )
foreach (var parent in cd.class_parents.types)
if (parent.names.Count == 1)
if (classes.ContainsKey(parent.FirstIdent.name))
classScope.classParent = classes[parent.FirstIdent.name];
base.visit(cd);
}
public override void visit(procedure_header node)
{
if ( node.template_args != null)
{
foreach (var template_name in node.template_args.idents)
{
AddSymbol(template_name, SymKind.template_param);
}
}
base.visit(node);
}
public override void visit(template_type_name node)
{
foreach (var name in node.template_args.idents)
{
AddSymbol(name, SymKind.template_param);
}
base.visit(node);
}
public override void visit(property_ident node)
{
AddSymbol(node, SymKind.property);
}
public virtual void AddSymbol(ident name, SymKind kind, type_definition td = null, SymbolAttributes attr = 0)
{
if (inPrivate)
attr &= SymbolAttributes.private_attr;
Current.AddSymbol(name, kind, td, attr);
}
public void AddSymbols(List<ident> names, SymKind kind, type_definition td = null, SymbolAttributes attr = 0)
{
foreach (var n in names)
{
AddSymbol(n, kind, td, attr);
}
}
public string Spaces(int n) => new string(' ', n);
public void OutputString(string s) => System.IO.File.AppendAllText(fname, s);
public void OutputlnString(string s = "") => System.IO.File.AppendAllText(fname, s + '\n');
public void Output(string fname)
{
#if DEBUG
this.fname = fname;
if (System.IO.File.Exists(fname))
System.IO.File.Delete(fname);
OutputElement(0, Root);
#endif
}
string fname;
public void OutputElement(int d, ScopeSyntax s)
{
OutputString(Spaces(d));
if (s == null)
throw new Exception("ggggggggg");
if (s is ParamsScopeSyntax)
{
OutputString(s.ToString() + ": ");
if (s.Symbols.Count > 0)
OutputlnString(string.Join(", ", s.Symbols.Select(x => x.ToString())));
}
else
{
OutputlnString(s.ToString());
if (s.Symbols.Count > 0)
OutputlnString(Spaces(d + 2) + string.Join(", ", s.Symbols.Select(x => x.ToString())));
}
foreach (var sc in s.Children)
OutputElement(d + 2, sc);
}
}
}

View file

@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PascalABCCompiler.SyntaxTree
{
public abstract class AbstractScopeCreator
{
public static bool IsScopeCreator(syntax_tree_node st)
{
if (st is compilation_unit || st is procedure_definition || st is statement_list ||
st is for_node || st is foreach_stmt || st is class_definition || st is record_type ||
st is function_lambda_definition || st is case_node) return true;
return false;
}
public virtual ScopeSyntax GetScope(syntax_tree_node st)
{
ScopeSyntax res = null;
if (st is compilation_unit p) res = CreateScope(p);
else if (st is procedure_definition pd) res = CreateScope(pd);
else if (st is statement_list sl) res = CreateScope(sl);
else if (st is for_node f) res = CreateScope(f);
else if (st is foreach_stmt fe) res = CreateScope(fe);
else if (st is class_definition cd) res = CreateScope(cd);
else if (st is record_type rt) res = CreateScope(rt);
else if (st is function_lambda_definition fld) res = CreateScope(fld);
else if (st is case_node cas) res = CreateScope(cas);
if (res != null) res.node = st;
return res;
}
protected abstract ScopeSyntax CreateScope(compilation_unit node);
protected abstract ScopeSyntax CreateScope(procedure_definition node);
protected abstract ScopeSyntax CreateScope(statement_list node);
protected abstract ScopeSyntax CreateScope(for_node node);
protected abstract ScopeSyntax CreateScope(foreach_stmt node);
protected abstract ScopeSyntax CreateScope(class_definition node);
protected abstract ScopeSyntax CreateScope(record_type node);
protected abstract ScopeSyntax CreateScope(function_lambda_definition node);
protected abstract ScopeSyntax CreateScope(case_node node);
}
class CachingScopeCreator : AbstractScopeCreator
{
Dictionary<syntax_tree_node, ScopeSyntax> map = new Dictionary<syntax_tree_node, ScopeSyntax>();
public override ScopeSyntax GetScope(syntax_tree_node st)
{
if (st == null) return null;
if (!map.ContainsKey(st))
{
var scope = base.GetScope(st);
if (scope != null) map.Add(st, scope);
else return null;
}
return map[st];
}
protected override ScopeSyntax CreateScope(compilation_unit node) {
if (node is unit_module um)
return new UnitScopeSyntax();
if (node is program_module pm)
return new ProgramScopeSyntax();
throw new ArgumentException("Unkmown global scope type!!!");
}
protected override ScopeSyntax CreateScope(procedure_definition node)
{
var name = node.proc_header?.name?.meth_name;
if (name == null)
name = "create";
var res = new ProcScopeSyntax(name);
if (node.proc_header is function_header fh)
{
res.AddSymbol(new ident("Result", node.source_context), SymKind.var, fh.return_type);
}
return res;
}
protected override ScopeSyntax CreateScope(statement_list node) => new StatListScopeSyntax();
protected override ScopeSyntax CreateScope(for_node node) => new ForScopeSyntax();
protected override ScopeSyntax CreateScope(foreach_stmt node) => new ForeachScopeSyntax();
protected override ScopeSyntax CreateScope(class_definition cd)
{
var td = cd.Parent as type_declaration;
var tname = td == null ? "NONAME" : td.type_name;
ScopeSyntax res = null;
if (cd.keyword == class_keyword.Class)
{
res = new ClassScopeSyntax(tname);
}
else if (cd.keyword == class_keyword.Record)
{
res = new RecordScopeSyntax(tname);
}
else if (cd.keyword == class_keyword.Interface)
{
res = new InterfaceScopeSyntax(tname);
}
return res;
}
protected override ScopeSyntax CreateScope(record_type node)
{
var td = node.Parent as type_declaration;
var tname = td == null ? "NONAME" : td.type_name;
return new RecordScopeSyntax(tname);
}
protected override ScopeSyntax CreateScope(function_lambda_definition node) => new LambdaScopeSyntax();
protected override ScopeSyntax CreateScope(case_node node) => new CaseScopeSyntax();
}
}

View file

@ -1,4 +1,5 @@
using System;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -17,10 +18,11 @@ using System.Text;
namespace PascalABCCompiler.SyntaxTree
{
public enum SymKind { var, field, param, procname, funcname, classname, recordname, interfacename };
public enum SymKind { var, field, param, procname, funcname, classname,
recordname, interfacename, template_param, type_alias, const_var, property };
[Flags]
public enum Attributes { class_attr = 1, varparam_attr = 2};
public enum SymbolAttributes { class_attr = 1, varparam_attr = 2, private_attr = 4};
public class SymInfoSyntax
{
@ -37,45 +39,130 @@ namespace PascalABCCompiler.SyntaxTree
public ident Id { get; set; }
public type_definition Td { get; set; }
public SymKind SK { get; set; }
public Attributes Attr { get; set; }
public SymInfoSyntax(ident Id, SymKind SK, type_definition Td = null, Attributes Attr = 0)
public SymbolAttributes Attr { get; set; }
public SymInfoSyntax(ident Id, SymKind SK, type_definition Td = null, SymbolAttributes Attr = 0)
{
this.Id = Id;
this.Td = Td;
this.SK = SK;
this.Attr = Attr;
}
public void AddAttribute(Attributes attr)
public void AddAttribute(SymbolAttributes attr)
{
Attr &= attr;
Attr |= attr;
}
}
public class ScopeSyntax
public abstract class ScopeSyntax
{
public syntax_tree_node node;
public ScopeSyntax Parent { get; set; }
public List<ScopeSyntax> Children = new List<ScopeSyntax>();
public List<SymInfoSyntax> Symbols = new List<SymInfoSyntax>();
public HashSet<SymInfoSyntax> Symbols = new HashSet<SymInfoSyntax>();
public override string ToString() => GetType().Name.Replace("Syntax", "");
protected virtual SymInfoSyntax searchSymbol(ident id)
{
foreach (var s in Symbols)
{
if (s.Id.name == id.name && (id.source_context == null ||
s.Id.source_context == null ||
s.Id.source_context.Less(id.source_context)))
{
return s;
}
}
return null;
}
public void AddSymbol(ident name, SymKind kind, type_definition td = null, SymbolAttributes attr = 0)
{
Symbols.Add(new SymInfoSyntax(name, kind, td, attr));
}
public virtual SymInfoSyntax bind(ident id)
{
return searchSymbol(id);
}
}
public class ScopeWithDefsSyntax : ScopeSyntax { } //
public class GlobalScopeSyntax : ScopeWithDefsSyntax { } // program_module unit_module
public abstract class GlobalScopeSyntax : ScopeWithDefsSyntax { } // program_module unit_module
public class NamedScopeSyntax : ScopeWithDefsSyntax
public class ProgramScopeSyntax : GlobalScopeSyntax { }
public class UnitScopeSyntax : GlobalScopeSyntax { }
public abstract class NamedScopeSyntax : ScopeWithDefsSyntax
{
public NamedScopeSyntax classParent;
public ident Name { get; set; }
public NamedScopeSyntax(ident Name) => this.Name = Name;
public override string ToString() => base.ToString() + "(" + Name + ")";
protected SymInfoSyntax searchInParentClass(ident id)
{
if (classParent == null) return null;
foreach (var symbol in classParent.Symbols)
{
if (symbol.Id.name == id.name && !symbol.Attr.HasFlag(SymbolAttributes.private_attr))
{
return symbol;
}
}
return null;
}
public override SymInfoSyntax bind(ident id)
{
SymInfoSyntax res = searchSymbol(id);
if (res != null) return res;
var cur = this;
while (cur != null)
{
res = cur.searchInParentClass(id);
if (res != null) return res;
cur = cur.classParent;
}
return res;
}
}
public class ProcScopeSyntax : NamedScopeSyntax // procedure_definition
{
{
public ProcScopeSyntax(ident Name) : base(Name) { }
public override SymInfoSyntax bind(ident id)
{
var res = classParent?.bind(id);
if (res != null) return res;
return base.bind(id);
}
}
public class ParamsScopeSyntax : ScopeSyntax { } // formal_parameters
public class ClassScopeSyntax : NamedScopeSyntax
public class ClassScopeSyntax
: NamedScopeSyntax
{
public ClassScopeSyntax(ident Name) : base(Name) { }
protected SymInfoSyntax searchSymbol(ident id)
{
//Console.WriteLine("searching " + id.ToString() + " in " + Name);
foreach (var s in Symbols)
{
// Console.WriteLine("Checking " + s.Id);
if (s.Id.name == id.name)
{
return s;
}
}
return null;
}
} //
public class RecordScopeSyntax : NamedScopeSyntax
{

View file

@ -1,225 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/*
ProgramScopeSyntax
BlockScopeSyntax
ProcScopeSyntax (name)
ParamsScopeSyntax
BlockScopeSyntax
StatListScopeSyntax (0)
StatListScopeSyntax (1)
StatListScopeSyntax (0)
StatListScopeSyntax (1)
*/
namespace PascalABCCompiler.SyntaxTree
{
// Визитор накопления легковесной синтаксической таблицы символов.
// Не дописан. Имеет большой потенциал применения
public partial class CollectLightSymInfoVisitor : BaseEnterExitVisitor
{
public ScopeSyntax Root;
/// <summary>
/// Текущее пространство имен
/// </summary>
public ScopeSyntax Current;
public static CollectLightSymInfoVisitor New => new CollectLightSymInfoVisitor();
public override void Enter(syntax_tree_node st)
{
ScopeSyntax t = null;
/*switch (st)
{
case program_module p:
case unit_module u:
t = new GlobalScopeSyntax();
Root = t;
break;
case procedure_definition p:
var name = p.proc_header?.name?.meth_name;
if (name == null)
name = "create";
var attr = p.proc_header.class_keyword ? Attributes.class_attr : 0;
if (name != null)
if (p.proc_header is function_header)
AddSymbol(name, SymKind.funcname,null, attr);
else AddSymbol(name, SymKind.procname, null, attr);
t = new ProcScopeSyntax(name);
break;
//case formal_parameters p:// Это неправильный Scope - он закрывался при выходе из секции формальных параметров, что неправильно
// t = new ParamsScopeSyntax();
// break;
case statement_list p:
t = new StatListScopeSyntax();
break;
case for_node p:
t = new ForScopeSyntax();
break;
case foreach_stmt p:
t = new ForeachScopeSyntax();
break;
//case repeat_node p: // не надо т.к. это StatListScope
// t = new RepeatScopeSyntax();
// break;
case case_node p:
t = new CaseScopeSyntax();
break;
case class_definition p:
var td = p.Parent as type_declaration;
var tname = td==null ? "NONAME" : td.type_name;
if (p.keyword == class_keyword.Class)
{
AddSymbol(tname, SymKind.classname);
t = new ClassScopeSyntax(tname);
}
else if (p.keyword == class_keyword.Record)
{
AddSymbol(tname, SymKind.recordname);
t = new RecordScopeSyntax(tname);
}
else if (p.keyword == class_keyword.Interface)
{
AddSymbol(tname, SymKind.interfacename);
t = new InterfaceScopeSyntax(tname);
}
break;
case function_lambda_definition p:
t = new LambdaScopeSyntax();
break;
}*/
if (st is program_module p1 || st is unit_module u)
{
t = new GlobalScopeSyntax();
Root = t;
}
else if (st is procedure_definition p2)
{
var name = p2.proc_header?.name?.meth_name;
if (name == null)
name = "create";
var attr = p2.proc_header.class_keyword ? Attributes.class_attr : 0;
if (name != null)
if (p2.proc_header is function_header)
AddSymbol(name, SymKind.funcname, null, attr);
else AddSymbol(name, SymKind.procname, null, attr);
t = new ProcScopeSyntax(name);
}
else if (st is statement_list p3)
{
t = new StatListScopeSyntax();
}
else if (st is for_node p4)
{
t = new ForScopeSyntax();
}
else if (st is foreach_stmt p5)
{
t = new ForeachScopeSyntax();
}
else if (st is case_node p6)
{
t = new CaseScopeSyntax();
}
else if (st is class_definition p7)
{
var td = p7.Parent as type_declaration;
var tname = td == null ? "NONAME" : td.type_name;
if (p7.keyword == class_keyword.Class)
{
AddSymbol(tname, SymKind.classname);
t = new ClassScopeSyntax(tname);
}
else if (p7.keyword == class_keyword.Record)
{
AddSymbol(tname, SymKind.recordname);
t = new RecordScopeSyntax(tname);
}
else if (p7.keyword == class_keyword.Interface)
{
AddSymbol(tname, SymKind.interfacename);
t = new InterfaceScopeSyntax(tname);
}
}
else if (st is function_lambda_definition p8)
{
t = new LambdaScopeSyntax();
}
if (t != null)
{
t.Parent = Current;
if (Current != null)
Current.Children.Add(t);
Current = t;
if (st is procedure_definition p)
{
if (p.proc_header is function_header fh)
{
AddSymbol(new ident("Result"), SymKind.var, fh.return_type);
}
}
}
}
public virtual void PreExitScope(syntax_tree_node st)
{
}
public override void Exit(syntax_tree_node st)
{
/*switch (st)
{
case program_module p:
case procedure_definition pd:
//case formal_parameters fp:
case statement_list stl:
case for_node f:
case foreach_stmt fe:
case class_definition cd:
case record_type rt:
case function_lambda_definition fld:
//case repeat_node rep:
case case_node cas:
PreExitScope(st);
if (Current != null)
Current = Current.Parent;
break;
}*/
if (st is program_module p || st is procedure_definition pd || st is statement_list stl ||
st is for_node f || st is foreach_stmt fe || st is class_definition cd || st is record_type rt ||
st is function_lambda_definition fld || st is case_node cas)
{
PreExitScope(st);
if (Current != null)
Current = Current.Parent;
}
}
public override void visit(var_def_statement vd)
{
var attr = vd.var_attr == definition_attribute.Static ? Attributes.class_attr : 0;
if (vd == null || vd.vars == null || vd.vars.list == null)
return;
AddSymbols(vd.vars.list, SymKind.var, vd.vars_type, attr);
base.visit(vd);
}
public override void visit(formal_parameters fp)
{
foreach (var pg in fp.params_list)
{
AddSymbols(pg.idents.idents, SymKind.param, pg.vars_type);
}
base.visit(fp);
}
public override void visit(for_node f)
{
if (f.create_loop_variable || f.type_name != null)
AddSymbol(f.loop_variable, SymKind.var, f.type_name);
base.visit(f);
}
}
}

View file

@ -1,70 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/*
GlobalScopeSyntax
BlockScopeSyntax
ProcScopeSyntax (name)
ParamsScopeSyntax
BlockScopeSyntax
StatListScopeSyntax (0)
StatListScopeSyntax (1)
StatListScopeSyntax (0)
StatListScopeSyntax (1)
*/
namespace PascalABCCompiler.SyntaxTree
{
public partial class CollectLightSymInfoVisitor
{
public virtual void AddSymbol(ident name, SymKind kind, type_definition td = null, Attributes attr = 0)
{
Current.Symbols.Add(new SymInfoSyntax(name, kind, td, attr));
}
public void AddSymbols(List<ident> names, SymKind kind, type_definition td = null, Attributes attr = 0)
{
foreach (var n in names)
{
AddSymbol(n, kind, td, attr);
}
}
public string Spaces(int n) => new string(' ', n);
public void OutputString(string s) => System.IO.File.AppendAllText(fname, s);
public void OutputlnString(string s = "") => System.IO.File.AppendAllText(fname, s + '\n');
public void Output(string fname)
{
#if DEBUG
this.fname = fname;
if (System.IO.File.Exists(fname))
System.IO.File.Delete(fname);
OutputElement(0, Root);
#endif
}
string fname;
public void OutputElement(int d, ScopeSyntax s)
{
OutputString(Spaces(d));
if (s == null)
throw new Exception("ggggggggg");
if (s is ParamsScopeSyntax)
{
OutputString(s.ToString()+": ");
if (s.Symbols.Count > 0)
OutputlnString(string.Join(", ", s.Symbols.Select(x => x.ToString())));
}
else
{
OutputlnString(s.ToString());
if (s.Symbols.Count > 0)
OutputlnString(Spaces(d + 2) + string.Join(", ", s.Symbols.Select(x => x.ToString())));
}
foreach (var sc in s.Children)
OutputElement(d + 2, sc);
}
}
}

View file

@ -45,6 +45,11 @@
<Compile Include="AllVarsInProcYieldsProba.cs" />
<Compile Include="BaseVisitors\CollectNamespaces.cs" />
<Compile Include="BaseVisitors\HasStatementVisitor.cs" />
<Compile Include="LightSymInfoVisitors\BindCollectLightSymInfo.cs" />
<Compile Include="LightSymInfoVisitors\CollectFullLightSymInfoVisitor.cs" />
<Compile Include="LightSymInfoVisitors\CollectLightSymInfoVisitor.cs" />
<Compile Include="LightSymInfoVisitors\LightScopeCreator.cs" />
<Compile Include="LightSymInfoVisitors\LightScopeHelperClasses.cs" />
<Compile Include="SugarVisitors\CacheFunctionVisitor.cs" />
<Compile Include="SugarVisitors\UnpackLambdaParametersVisitor.cs" />
<Compile Include="TeacherControl\TeacherControl.cs" />
@ -52,9 +57,6 @@
<Compile Include="BaseVisitors\SmallHelperVisitors.cs" />
<Compile Include="ChangeWhileVisitor.cs" />
<Compile Include="CheckingVisitors\UnnamedRecordsCheckErrorsVisitor.cs" />
<Compile Include="LightSymInfoVisitors\LightScopeHelperClasses.cs" />
<Compile Include="LightSymInfoVisitors\SymInfoCollect1.cs" />
<Compile Include="LightSymInfoVisitors\SymInfoCollect1Helper.cs" />
<Compile Include="PatternsVisitors\ExtendedIsDesugaringVisitor.cs" />
<Compile Include="PatternsVisitors\PatternsDesugaringVisitor.cs" />
<Compile Include="PatternsVisitors\ReplaceNamesInIsVarVisitor.cs" />

View file

@ -10,7 +10,7 @@ namespace PascalABCCompiler.SyntaxTreeConverters
// Первое предназначение - вынести последовательность из заголовка в foreach до foreach как отдельное присваивание
// Второе предназначение - переименовать все переменные, совпадающие по имени с типом T обобщенного класса, в котором находится метод, содержащий лямбду
public class VarNamesInMethodsWithSameNameAsClassGenericParamsReplacer: CollectLightSymInfoVisitor
public class VarNamesInMethodsWithSameNameAsClassGenericParamsReplacer: CollectFullLightSymInfoVisitor
{
/// <summary>
/// Надо приводить к нижнему регистру
@ -27,11 +27,13 @@ namespace PascalABCCompiler.SyntaxTreeConverters
// Описание переменной в словарь добавляется только если она описана в методе, но вне лямбды, поскольку в лямбде конфликтов имен нет
// При выходе из пространства имен мы проверяем, есть ли в словаре такое значение, и если да, очищаем его, присваивая null
// Переименовывать будем все имена name если ключ name есть в словаре и d[name] != null
public static new VarNamesInMethodsWithSameNameAsClassGenericParamsReplacer New
public VarNamesInMethodsWithSameNameAsClassGenericParamsReplacer(compilation_unit pm) : base(pm)
{
get => new VarNamesInMethodsWithSameNameAsClassGenericParamsReplacer();
}
public override void AddSymbol(ident name, SymKind kind, type_definition td = null, Attributes attr = 0)
public override void AddSymbol(ident name, SymKind kind, type_definition td = null, SymbolAttributes attr = 0)
{
if (name == null || name.name == null)
{
@ -163,7 +165,7 @@ namespace PascalABCCompiler.SyntaxTreeConverters
// это точно надо захватывать
}
public override void visit(var_def_statement vds)
public override void visit(var_def_statement vds)
{
// имена обойти отдельно, инициализатор - отдельно
foreach (var id in vds.vars.idents)

View file

@ -0,0 +1,33 @@
call Studio.bat /t:rebuild "/property:Configuration=Debug" "/p:Platform=Any CPU" PascalABCNET.sln
@IF %ERRORLEVEL% NEQ 0 GOTO ERROR
cd ReleaseGenerators
..\bin\pabcnetc RebuildStandartModules.pas /rebuild
@IF %ERRORLEVEL% NEQ 0 GOTO ERROR
cd PABCRtl
..\..\bin\pabcnetc PABCRtl.pas /rebuild
@IF %ERRORLEVEL% NEQ 0 GOTO ERROR
..\sn.exe -Vr PABCRtl.dll
..\sn.exe -R PABCRtl.dll KeyPair.snk
..\sn.exe -Vu PABCRtl.dll
copy PABCRtl.dll ..\..\bin\Lib
cd ..
ExecHide.exe gacutil.exe /u PABCRtl
ExecHide.exe gacutil.exe /i ..\bin\Lib\PABCRtl.dll
..\bin\pabcnetc RebuildStandartModules.pas /rebuild
@IF %ERRORLEVEL% NEQ 0 GOTO ERROR
cd ..\bin
REM MPGORunner.exe
cd ..
GOTO EXIT
:ERROR
PAUSE
:EXIT