Skip to content

Commit

Permalink
GH-392 Make sure that break & continue are not used outside of the co…
Browse files Browse the repository at this point in the history
…ntrolled scopes
  • Loading branch information
dzikoysk committed Nov 2, 2019
1 parent c30e679 commit 38dbbc1
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2015-2019 Dzikoysk
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.panda_lang.framework.design.architecture.statement;

public final class ScopeUtils {

private ScopeUtils() { }

/**
* Check if one of a parent scopes inherits from the given type
*
* @param currentScope the current scope
* @param expectedParent the type of parent scope to look for
* @return true if parent scope of the given type was found, otherwise false
*/
public static boolean lookFor(Scope currentScope, Class<? extends Scope> expectedParent) {
Scope parent = currentScope;

do {
if (expectedParent.isAssignableFrom(parent.getClass())) {
return true;
}

parent = parent.getParent().orElse(null);
} while (parent != null);

return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public InterceptorData handle(InterceptorData interceptorData, Context context)
}

interceptorData.addElement(currentSource.getLocation());
interceptorData.addElement(result.getSource());
interceptorData.addElement(result);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@

package org.panda_lang.panda.language.interpreter.parser.scope.branching;

import org.panda_lang.framework.design.architecture.dynamic.ControlledScope;
import org.panda_lang.framework.design.architecture.statement.Scope;
import org.panda_lang.framework.design.architecture.statement.ScopeUtils;
import org.panda_lang.framework.design.interpreter.parser.Context;
import org.panda_lang.framework.design.interpreter.parser.pipeline.Pipelines;
import org.panda_lang.framework.design.interpreter.source.SourceLocation;
import org.panda_lang.framework.design.interpreter.token.Snippet;
import org.panda_lang.framework.language.interpreter.parser.PandaParserFailure;
import org.panda_lang.framework.language.resource.syntax.keyword.Keywords;
import org.panda_lang.panda.language.interpreter.bootstraps.context.BootstrapInitializer;
import org.panda_lang.panda.language.interpreter.bootstraps.context.ParserBootstrap;
Expand All @@ -42,8 +46,12 @@ protected BootstrapInitializer initialize(Context context, BootstrapInitializer
}

@Autowired
void parseBreak(@Component Scope block, @Inter SourceLocation location) {
block.addStatement(new Break(location));
void parseBreak(Context context, @Component Scope scope, @Inter SourceLocation location, @Inter Snippet source) {
if (!ScopeUtils.lookFor(scope, ControlledScope.class)) {
throw new PandaParserFailure(context, source, "Break cannot be used outside of the looping block");
}

scope.addStatement(new Break(location));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@

package org.panda_lang.panda.language.interpreter.parser.scope.branching;

import org.panda_lang.framework.design.architecture.dynamic.ControlledScope;
import org.panda_lang.framework.design.architecture.statement.Scope;
import org.panda_lang.framework.design.architecture.statement.ScopeUtils;
import org.panda_lang.framework.design.interpreter.parser.Context;
import org.panda_lang.framework.design.interpreter.parser.pipeline.Pipelines;
import org.panda_lang.framework.design.interpreter.source.SourceLocation;
import org.panda_lang.framework.design.interpreter.token.Snippet;
import org.panda_lang.framework.language.interpreter.parser.PandaParserFailure;
import org.panda_lang.framework.language.resource.syntax.keyword.Keywords;
import org.panda_lang.panda.language.interpreter.bootstraps.context.BootstrapInitializer;
import org.panda_lang.panda.language.interpreter.bootstraps.context.ParserBootstrap;
Expand All @@ -42,8 +46,12 @@ protected BootstrapInitializer initialize(Context context, BootstrapInitializer
}

@Autowired
void parseContinue(@Component Scope block, @Inter SourceLocation location) {
block.addStatement(new Continue(location));
void parseContinue(Context context, @Component Scope scope, @Inter SourceLocation location, @Inter Snippet source) {
if (!ScopeUtils.lookFor(scope, ControlledScope.class)) {
throw new PandaParserFailure(context, source, "Continue cannot be used outside of the looping block");
}

scope.addStatement(new Continue(location));
}

}

0 comments on commit 38dbbc1

Please sign in to comment.