public void Visit(Assignment asg) { if (asg.LoadExp != null) { asg.LoadExp.Accept(this); } asg.Exp.Accept(this); var varName = asg.VarName; StaticEnvBase.VarInfo varInfo; if (asg.LoadExp != null) { var structType = asg.LoadExp.Type as StructType; Raise <TypeCheckException> .IfIsNull(structType, "Can apply dot only on structs"); var field = structType.Fields.FirstOrDefault(f => f.Name == varName); Raise <TypeCheckException> .IfIsNull(field, "Given struct type has not given field"); Raise <TypeCheckException> .IfAreNotSame(field.Type, asg.Exp.Type, "Wrong type in assignment"); varInfo = new StaticEnvBase.VarInfo(varName, asg.Exp.Type, StaticEnvBase.Kind.Field, field); } else if (_staticEnv.TryGetVariable(varName, out varInfo)) { if (!varInfo.Type.Equals(_result)) { throw new TypeCheckException(string.Format( "Cannot re-assign {0} with a value of different type", varName)); } } else { var info = _currFunc.AddVariable(varName, asg.Exp.Type); varInfo = new StaticEnvBase.VarInfo(varName, asg.Exp.Type, StaticEnvBase.Kind.Var, info); _staticEnv.SetVariable(varName, varInfo); } asg.Var = varInfo; }
public void Visit(FunctionDecl funcDecl) { Raise <TypeCheckException> .If(_funcDecls.ContainsKey(funcDecl.Name), "Function with existing name!"); funcDecl.ReturnType = GetType(funcDecl.ReturnTypeName); var previousStaticEnv = _staticEnv; _staticEnv = new StaticEnv(new OutmostStaticEnv()); foreach (var p in funcDecl.Params) { p.Type = GetType(p.TypeName); Raise <TypeCheckException> .IfAreSame(p.Type, _voidType, "Struct fields cannot be void"); var vInfo = new StaticEnvBase.VarInfo(p.Name, p.Type, StaticEnvBase.Kind.Param, p); _staticEnv.SetVariable(p.Name, vInfo); } _funcDecls.Add(funcDecl.Name, funcDecl); // Must be put here to allow recursion... var prevFunc = _currFunc; _currFunc = funcDecl; funcDecl.Body.Accept(this); _currFunc = prevFunc; _staticEnv = previousStaticEnv; }
public void Visit(Assignment asg) { if (asg.LoadExp != null) { asg.LoadExp.Accept(this); } asg.Exp.Accept(this); var varName = asg.VarName; StaticEnvBase.VarInfo varInfo; if (asg.LoadExp != null) { var structType = asg.LoadExp.Type as StructType; Raise<TypeCheckException>.IfIsNull(structType, "Can apply dot only on structs"); var field = structType.Fields.FirstOrDefault(f => f.Name == varName); Raise<TypeCheckException>.IfIsNull(field, "Given struct type has not given field"); Raise<TypeCheckException>.IfAreNotSame(field.Type, asg.Exp.Type, "Wrong type in assignment"); varInfo = new StaticEnvBase.VarInfo(varName, asg.Exp.Type, StaticEnvBase.Kind.Field, field); } else if (_staticEnv.TryGetVariable(varName, out varInfo)) { if (!varInfo.Type.Equals(_result)) { throw new TypeCheckException(string.Format( "Cannot re-assign {0} with a value of different type", varName)); } } else { var info = _currFunc.AddVariable(varName, asg.Exp.Type); varInfo = new StaticEnvBase.VarInfo(varName, asg.Exp.Type, StaticEnvBase.Kind.Var, info); _staticEnv.SetVariable(varName, varInfo); } asg.Var = varInfo; }
public void Visit(FunctionDecl funcDecl) { Raise<TypeCheckException>.If(_funcDecls.ContainsKey(funcDecl.Name), "Function with existing name!"); funcDecl.ReturnType = GetType(funcDecl.ReturnTypeName); var previousStaticEnv = _staticEnv; _staticEnv = new StaticEnv(new OutmostStaticEnv()); foreach (var p in funcDecl.Params) { p.Type = GetType(p.TypeName); Raise<TypeCheckException>.IfAreSame(p.Type, _voidType, "Struct fields cannot be void"); var vInfo = new StaticEnvBase.VarInfo(p.Name, p.Type, StaticEnvBase.Kind.Param, p); _staticEnv.SetVariable(p.Name, vInfo); } _funcDecls.Add(funcDecl.Name, funcDecl); // Must be put here to allow recursion... var prevFunc = _currFunc; _currFunc = funcDecl; funcDecl.Body.Accept(this); _currFunc = prevFunc; _staticEnv = previousStaticEnv; }