using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
using Canon.Core.SemanticParser;
namespace Canon.Core.SyntaxNodes;
///
/// 使用数值产生式事件的事件参数
///
public class NumberConstValueEventArgs : EventArgs
{
///
/// 是否含有负号
///
public bool IsNegative { get; init; }
///
/// 数值记号
///
public required NumberSemanticToken Token { get; init; }
}
///
/// 使用字符产生式事件的事件参数
///
public class CharacterConstValueEventArgs : EventArgs
{
///
/// 字符记号
///
public required CharacterSemanticToken Token { get; init; }
}
public class ConstValue : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.ConstValue;
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
RaiseGeneratorEvent();
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
RaiseGeneratorEvent();
}
private PascalType? _constType;
///
/// 该ConstValue代表的类型
///
/// 尚未分析该类型
public PascalType ConstType
{
get
{
if (_constType is null)
{
throw new InvalidOperationException("ConstType has not been set");
}
return _constType;
}
set
{
_constType = value;
}
}
///
/// 使用数值产生式的事件
///
public event EventHandler? OnNumberGenerator;
///
/// 使用字符产生式的事件
///
public event EventHandler? OnCharacterGenerator;
private void RaiseGeneratorEvent()
{
if (Children.Count == 2)
{
OperatorSemanticToken operatorSemanticToken = Children[0].Convert().Token
.Convert();
NumberSemanticToken numberSemanticToken = Children[1].Convert().Token
.Convert();
OnNumberGenerator?.Invoke(this, new NumberConstValueEventArgs
{
Token = numberSemanticToken,
IsNegative = operatorSemanticToken.OperatorType == OperatorType.Minus
});
return;
}
SemanticToken token = Children[0].Convert().Token;
if (token.TokenType == SemanticTokenType.Number)
{
OnNumberGenerator?.Invoke(this,
new NumberConstValueEventArgs
{
Token = token.Convert()
});
}
else
{
OnCharacterGenerator?.Invoke(this, new CharacterConstValueEventArgs
{
Token = token.Convert()
});
}
OnNumberGenerator = null;
OnCharacterGenerator = null;
}
public static ConstValue Create(List children)
{
return new ConstValue { Children = children };
}
public override void GenerateCCode(CCodeBuilder builder)
{
//获取常量值
var token = Children[0].Convert().Token;
//constValue -> 'letter'
if (token.TokenType == SemanticTokenType.Character)
{
builder.AddString(" '" + token.LiteralValue + "'");
}
else
{
builder.AddString(" ");
// constValue -> +num | -num | num
foreach (var c in Children)
{
builder.AddString(c.Convert().Token.LiteralValue);
}
}
}
}