c语言context函数,C语言解释器-7 一切的基础 Context类

Context是构建语法树的基础,程序由一个个Context组成,比如变量(申明),语句,块,函数,控制结构等。

看看Context类的Run方法,很能说明问题:

public virtual void Run(Context ctx)

{

// 正在运行标记

IsRunning = true;

foreach (Context stx in Children)

{

try

{

if (stx is Statement || stx is Block)

{

stx.Run(this);

}

else

if (stx is Variable)

{

//局部变量,需要登记,以便将来释放

LocalVariables.Add(stx.Name);

stx.Run(this);

}

else

if (stx is ConstantInitialize)

{

//常量,出现在全局Context中,需要记录。在运行到最后的时候释放

m_constantVariableDict.Add((stx as ConstantInitialize).VariableName, stx);

stx.Run(this);

}

else

if (stx is Function.FunctionDefine)

{

// 仅运行main函数,其他函数在调用时运行

if (stx.Name == MainFunctionName)

{

m_mainFunction = stx as Function.FunctionDefine;

m_mainFunction.Body.Run(this);

}

}

}

catch (RuntimeException re)

{

if (OnRuntimeError != null)

OnRuntimeError(stx, re.Message);

}

} // foreach

// 释放局部变量

FreeLocalVariables();

IsRunning = false;

}

设定所有的Context都应该有个Parent,如果Parent为null,则表示为全局的Context。也即Yacc脚本中的Program规则。

主要的属性有:

// Public

public Context Parent;

public List Children;

public string Name;

public List LocalVariables;

public bool IsFirstRunning = true;

public LocationInfo Location;

public event EventHandler OnRuntimeError;

一些全局性的东西,申明为静态,主要与语法分析相关。还包括内部定义函数。

// Static

public static string MainFunctionName = "main";

private static int AnonymousVariableCount = 0;

private static string AnonymousVariableNamePrefix = "var";

private static bool ContextIsRunning = false;

public static Dictionary KeywordDict = new Dictionary();

public static Dictionary DataTypeKeywordDict = new Dictionary();

public static Dictionary ControlKeywordDict = new Dictionary();

public static Dictionary TypeCombinationDict = new Dictionary();

public static Dictionary InternalFunctionDict = new Dictionary();

public static Memory Memory = new Memory("");

public static bool IsRunning

{

get { return ContextIsRunning; }

protected set { ContextIsRunning = value; }

}

public static string GetAnonymousName()

{

return string.Format("${0}_{1}$", AnonymousVariableNamePrefix, ++AnonymousVariableCount);

}

public static string GetAnonymousName(string prefix)

{

return string.Format("${0}_{1}$", prefix, ++AnonymousVariableCount);

}

public static string GetAnonymousName(DataTypeInfo dti)

{

return string.Format("${0}_{1}_{2}{3}$",

AnonymousVariableNamePrefix,

DataTypeInfo.StringFromType(dti.BaseType),

dti.PointerCount > 0 ? "ptr_" : "",

++AnonymousVariableCount);

}

public static bool IsKeyword(string str)

{

if (KeywordDict.Count == 0)

{

// primitive type

KeywordDict.Add("void", true);

KeywordDict.Add("char", true);

KeywordDict.Add("short", true);

KeywordDict.Add("int", true);

KeywordDict.Add("float", true);

KeywordDict.Add("signed", true);

KeywordDict.Add("unsigned", true);

// control

KeywordDict.Add("if", true);

KeywordDict.Add("else", true);

KeywordDict.Add("for", true);

KeywordDict.Add("do", true);

KeywordDict.Add("while", true);

KeywordDict.Add("switch", true);

KeywordDict.Add("case", true);

KeywordDict.Add("continue", true);

KeywordDict.Add("break", true);

KeywordDict.Add("return", true);

// misc

KeywordDict.Add("sizeof", true);

}

return KeywordDict.ContainsKey(str);

}

public static bool IsDataType(string str)

{

if (DataTypeKeywordDict.Count == 0)

{

DataTypeKeywordDict.Add("void", PrimitiveDataType.VoidType);

DataTypeKeywordDict.Add("char", PrimitiveDataType.CharType);

DataTypeKeywordDict.Add("short", PrimitiveDataType.ShortType);

DataTypeKeywordDict.Add("int", PrimitiveDataType.IntType);

DataTypeKeywordDict.Add("float", PrimitiveDataType.FloatType);

DataTypeKeywordDict.Add("signed", PrimitiveDataType.SignedType);

DataTypeKeywordDict.Add("unsigned", PrimitiveDataType.UnsignedType);

}

return DataTypeKeywordDict.ContainsKey(str);

}

public static bool IsControlFlow(string str)

{

if (ControlKeywordDict.Count == 0)

{

ControlKeywordDict.Add("if", true);

ControlKeywordDict.Add("else", true);

ControlKeywordDict.Add("for", true);

ControlKeywordDict.Add("do", true);

ControlKeywordDict.Add("while", true);

ControlKeywordDict.Add("switch", true);

ControlKeywordDict.Add("case", true);

ControlKeywordDict.Add("continue", true);

ControlKeywordDict.Add("break", true);

ControlKeywordDict.Add("return", true);

}

return ControlKeywordDict.ContainsKey(str);

}

public static bool IsInternalFunction(string str)

{

return InternalFunctionDict.ContainsKey(str);

}

public static void RegisterInternalFunction(string name)

{

if (!InternalFunctionDict.ContainsKey(name))

InternalFunctionDict.Add(name, true);

}

注意到相当多的静态方法使用字符串字典。

另外一个重要的方法是FindByName(string name),该方法用于查找符合指定名字的已定义的Context,这是检查或查找变量、函数的重要手段。

public virtual Context FindByName(string str)

{

if (m_nameDict.ContainsKey(str))

return m_nameDict[str];

Context stx = this.Parent;

if (stx != null)

return stx.FindByName(str);

return null;

}

一些语法结构,如控制结构、函数,需要知道一些额外信息,因此需要以下辅助方法:

public bool IsInFunction

{

get

{

Context stx = Parent;

while (stx != null)

{

if (stx is Function.FunctionDefine)

return true;

stx = stx.Parent;

}

return false;

}

}

public Function.FunctionDefine ParentFunction

{

get

{

Context stx = Parent;

while (stx != null)

{

if (stx is Function.FunctionDefine)

return stx as Function.FunctionDefine;

stx = stx.Parent;

}

return null;

}

}

public Block ParentBlock

{

get

{

Context stx = Parent;

while (stx != null)

{

if (stx is Block)

return stx as Block;

stx = stx.Parent;

}

return null;

}

}

public bool IsInLoop

{

get

{

Context stx = Parent;

while (stx != null)

{

if (stx is ControlFlow.ForLoop || stx is ControlFlow.DoWhileLoop || stx is ControlFlow.WhileLoop)

return true;

stx = stx.Parent;

}

return false;

}

}

public bool IsInSwitch

{

get

{

Context stx = this;

while (stx != null)

{

if (stx is ControlFlow.Switch)

return true;

stx = stx.Parent;

}

return false;

}

}

public Context GlobalContex

{

get

{

if (this.Parent == null)

return this;

else

return this.Parent.GlobalContex;

}

}

常量应该在最后一刻释放。相同的还有函数的参数定义。SharpC将函数的参数视为特殊的局部变量:在函数第一次运行时分配空间,而在解释器运行到最后时才释放。也算是一种简单的优化。

~Context()

{

FreeConstantVariables();

if (Parent == null)

{

if (m_mainFunction != null)

FreeFunctionArguments(m_mainFunction);

FreeAllFunctionArguments(this);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值