// minden scope-ban nézünk egyezést. Az első-be ismétlődés találásánál errort dobunk. // a többiben figyelmeztetjük a programozót, hogy name shadow-ol public bool Add(Symbol symbol, dynamic value, Stack <Scope> scopeStack) { foreach (KeyValuePair <Symbol, dynamic> pair in table) { if (pair.Key.Name == symbol.Name) { ErrorMsg = $"Redefinition of variable '{symbol.Name}'"; return(false); } } if (scopeStack.Count != 0) { scopeStack.Pop(); // a mostani scope-ot kivesszök foreach (var scope in scopeStack) { foreach (KeyValuePair <Symbol, dynamic> pair in scope.table) { if (pair.Key.Name == symbol.Name && pair.Key.IsIterator == false) { WarningMsg = $"Name shadowing. There is already a variable defined as '{symbol.Name}'"; break; } else if (pair.Key.Name == symbol.Name && pair.Key.IsIterator == true) { ErrorMsg = $"Name shadowing. You cannot declare a variable with the name of an iterator ({symbol.Name})"; return(false); } } } } if (!Assigner.CanAssign(symbol.Type, value)) { ErrorMsg = Assigner.ErrorMsg; return(false); } table[symbol] = value; return(true); }
// úgy adja hozzá, hogy csak az adott scope-ban néz egyezést // így hozzuk létre az iterátorokat public bool Add(Symbol symbol, dynamic value) { foreach (KeyValuePair <Symbol, dynamic> pair in table) { if (pair.Key.Name == symbol.Name) { ErrorMsg = $"Redefinition of variable '{symbol.Name}'"; return(false); } } if (!Assigner.CanAssign(symbol.Type, value)) { ErrorMsg = Assigner.ErrorMsg; return(false); } table[symbol] = value; return(true); }
private bool SetVariableValueByName(string id, dynamic value, OtherBinaryOperation obo, ParserRuleContext context) { if (value == null) { return(false); } dynamic currentValue = GetVariableValueByName(id); string currentType = GetVariableTypeByName(id); bool complexAssign = obo != null; if (complexAssign) { var newValue = obo.Calculate(currentValue, value); string warningMsg = obo.WarningMsg; if (warningMsg != null) { alerts.Add(new warning(context.Start.Line, warningMsg)); } if (newValue == null) { alerts.Add(new error(context.Start.Line, obo.ErrorMsg)); return(false); } bool success = currentScope.ReplaceKey(id, newValue); if (!success) { foreach (Scope sc in symbolTable) { success = sc.ReplaceKey(id, newValue); if (success) { break; } } } } else { if (Assigner.CanAssign(currentType, value)) { bool success = currentScope.ReplaceKey(id, value); if (!success) { foreach (Scope sc in symbolTable) { success = sc.ReplaceKey(id, value); if (success) { break; } } } } else { alerts.Add(new error(context.Start.Line, Assigner.ErrorMsg)); return(false); } } return(true); }
/* assign_statement: (simple_modifyable_exp EQ operation SEMI) | * (simple_modifyable_exp other_binary_op operation SEMI); * */ public override object VisitAssign_statement([NotNull] DDD_layout_scriptParser.Assign_statementContext context) { var toModify = context.simple_modifyable_exp(); if (toModify.ID() != null) { string id = toModify.ID().GetText(); Symbol symbol = GetVariableByName(id); dynamic value = GetVariableValueByName(id); if (value == null) { alerts.Add(new error(context.Start.Line, $"Cannot assign to an undefined variable {id}")); return(null); } if (symbol.Const && !(value is UnitializedObject)) { alerts.Add(new error(context.Start.Line, $"Left hand side refers to a constant expression {id}")); return(null); } dynamic opValue = VisitOperation(context.operation()); if (opValue is UnitializedObject) { alerts.Add(new error(context.Start.Line, $"You cannot assign uninitialized varible to another one")); return(null); } // az értéket teljesen felülírjuk if (context.EQ() != null) { SetVariableValueByName(id, opValue, context); } // az értéket változtatjuk ( += v -= v *= v /= ) else { if (value is UnitializedObject) { alerts.Add(new error(context.Start.Line, $"You cannot use += -= *= /= on an uninitalized variable ({id})")); return(null); } SetVariableValueByName(id, opValue, new OtherBinaryOperation(context.other_binary_op().GetText()), context); } } // vektor valamelyik koordinátájával csinálunk valamit. else { var xyz = toModify.modifiable_xyz(); string xyzText = xyz.GetText(); string id = xyz.ID().GetText(); Symbol symbol = GetVariableByName(id); dynamic value = GetVariableValueByName(id); if (value == null) { alerts.Add(new error(context.Start.Line, $"Cannot assign to an undefined variable {id}")); return(null); } if (symbol.Const && !(value is UnitializedObject)) { alerts.Add(new error(context.Start.Line, $"Left hand side refers to a constant expression {id}")); return(null); } if (symbol.Type != "Vec3" && symbol.Type != "Unknown") { alerts.Add(new error(context.Start.Line, "Cannot access coordinates of a non Vec3 type")); return(null); } else if (value is UnitializedObject) { alerts.Add(new error(context.Start.Line, "Accessing coordinates of an unitialized Vec3")); return(null); } vec3 originalVec3 = (vec3)value; dynamic opValue = VisitOperation(context.operation()); if (!Assigner.CanAssign("Float", opValue)) { alerts.Add(new error(context.Start.Line, Assigner.ErrorMsg)); return(null); } if (xyzText.Contains(".x")) { if (context.EQ() != null) { dynamic res = opValue; originalVec3.x = res; SetVariableValueByName(id, originalVec3, null); } else { OtherBinaryOperation obo = new OtherBinaryOperation(context.other_binary_op().GetText()); dynamic res = obo.Calculate(originalVec3.x, opValue); originalVec3.x = res; SetVariableValueByName(id, originalVec3, null); } } else if (xyzText.Contains(".y")) { if (context.EQ() != null) { dynamic res = opValue; originalVec3.y = res; SetVariableValueByName(id, originalVec3, null); } else { OtherBinaryOperation obo = new OtherBinaryOperation(context.other_binary_op().GetText()); dynamic res = obo.Calculate(originalVec3.y, opValue); originalVec3.y = res; SetVariableValueByName(id, originalVec3, null); } } else if (xyzText.Contains(".z")) { if (context.EQ() != null) { dynamic res = opValue; originalVec3.z = res; SetVariableValueByName(id, originalVec3, null); } else { OtherBinaryOperation obo = new OtherBinaryOperation(context.other_binary_op().GetText()); dynamic res = obo.Calculate(originalVec3.z, opValue); originalVec3.z = res; SetVariableValueByName(id, originalVec3, null); } } } return(null); }