pascalabcnet/SyntaxVisitors/LightSymInfoVisitors/SymInfoCollect1.cs

159 lines
5.9 KiB
C#
Raw Permalink Normal View History

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
{
2018-12-14 16:33:59 +03:00
// Визитор накопления легковесной синтаксической таблицы символов.
// Не дописан. Имеет большой потенциал применения
2017-10-26 19:39:20 +03:00
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:
2017-10-26 19:39:20 +03:00
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";
2017-11-02 12:21:02 +03:00
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);
2017-10-26 19:39:20 +03:00
t = new ProcScopeSyntax(name);
break;
//case formal_parameters p:// Это неправильный Scope - он закрывался при выходе из секции формальных параметров, что неправильно
// t = new ParamsScopeSyntax();
// break;
case statement_list p:
t = new StatListScopeSyntax();
break;
2017-10-26 19:39:20 +03:00
case for_node p:
t = new ForScopeSyntax();
break;
case foreach_stmt p:
t = new ForeachScopeSyntax();
break;
/*case repeat_node p: // не надо т.к. это StatListScope
2017-10-26 19:39:20 +03:00
t = new RepeatScopeSyntax();
break;*/
case case_node p:
t = new CaseScopeSyntax();
break;
case class_definition p:
var td = p.Parent as type_declaration;
2017-11-02 12:21:02 +03:00
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);
}
2017-10-26 19:39:20 +03:00
break;
case function_lambda_definition p:
t = new LambdaScopeSyntax();
break;
}
if (t != null)
{
t.Parent = Current;
if (Current != null)
Current.Children.Add(t);
Current = t;
2017-10-26 19:39:20 +03:00
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:
2017-10-26 19:39:20 +03:00
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);
Current = Current.Parent;
break;
}
}
public override void visit(var_def_statement vd)
{
2017-11-02 12:21:02 +03:00
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);
2017-10-26 19:39:20 +03:00
base.visit(vd);
}
2017-10-26 19:39:20 +03:00
public override void visit(formal_parameters fp)
{
2017-10-26 19:39:20 +03:00
foreach (var pg in fp.params_list)
{
AddSymbols(pg.idents.idents, SymKind.param, pg.vars_type);
2017-10-26 19:39:20 +03:00
}
base.visit(fp);
}
2017-10-26 19:39:20 +03:00
public override void visit(for_node f)
{
2017-10-26 19:39:20 +03:00
if (f.create_loop_variable || f.type_name != null)
AddSymbol(f.loop_variable, SymKind.var, f.type_name);
base.visit(f);
}
}
}