pascalabcnet/SyntaxVisitors/LightSymInfoVisitors/SymInfoCollect1.cs
Mikhalkovich Stanislav 1327baaa48 fix #1147
Многовато кода для маленького фикса ))
2019-06-15 13:25:44 +03:00

159 lines
5.9 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 (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);
Current = Current.Parent;
break;
}
}
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);
}
}
}