Index: trunk/jenga/include/smoothie/LexicalScoping.h
===================================================================
--- trunk/jenga/include/smoothie/LexicalScoping.h	(revision 174)
+++ trunk/jenga/include/smoothie/LexicalScoping.h	(revision 174)
@@ -0,0 +1,75 @@
+#pragma once
+
+#include <windows.h>
+
+enum SCOPE_TYPE{
+	//ベース
+	SCOPE_TYPE_BASE,
+
+	//分岐
+	SCOPE_TYPE_IF,
+
+	//ループ
+	SCOPE_TYPE_DO,
+	SCOPE_TYPE_FOR,
+	SCOPE_TYPE_WHILE,
+
+	//ケース分け
+	SCOPE_TYPE_SELECT,
+};
+
+class CScope{
+protected:
+	int level;
+	int StartAddress;
+	SCOPE_TYPE TypeOfStatement;
+
+	DWORD *pBreakSchedule;
+	int nBreakSchedule;
+
+public:
+	CScope( int level, int addr, SCOPE_TYPE TypeOfStatement );
+	~CScope();
+
+	int GetStartAddress();
+	SCOPE_TYPE GetTypeOfStatement();
+
+	virtual void Break() = 0;
+	virtual void RunScheduleOfBreak() = 0;
+};
+
+class CLexicalScopes{
+protected:
+	CScope **ppScopes;
+	int level;
+
+	CScope *SearchScope( SCOPE_TYPE TypeOfStatement );
+
+	virtual CScope *CreateScope( int level, int addr, SCOPE_TYPE TypeOfStatement ) = 0;
+public:
+	CLexicalScopes();
+	~CLexicalScopes();
+
+	//初期化（関数コンパイルの開始時に呼び出される）
+	void Init(int addr);
+
+	// スコープを開始
+	void Start( int addr, SCOPE_TYPE TypeOfStatement );
+
+	//スコープを終了
+	void End();
+
+	//スコープ抜け出しステートメント
+	void Break();
+
+	int GetNowLevel(void);
+	void SetNowLevel( int level );
+	int GetStartAddress(void);
+
+	//スコープ終了時のデストラクタ呼び出し
+	virtual void CallDestructorsOfScopeEnd() = 0;
+
+	//Returnステートメント用のデストラクタ呼び出し
+	virtual void CallDestructorsOfReturn( int BaseLevel = 0 ) = 0;
+};
+
Index: trunk/jenga/include/smoothie/Smoothie.h
===================================================================
--- trunk/jenga/include/smoothie/Smoothie.h	(revision 173)
+++ trunk/jenga/include/smoothie/Smoothie.h	(revision 174)
@@ -3,4 +3,5 @@
 #include "Source.h"
 #include "ObjectModule.h"
+#include "LexicalScoping.h"
 
 class Smoothie{
@@ -20,5 +21,9 @@
 		static NamespaceScopesCollection importedNamespaces;
 
+		// コンパイル中のクラス
 		static const CClass *pCompilingClass;
+
+		// レキシカルスコープの状態
+		static CLexicalScopes *pLexicalScopes;
 	};
 
Index: trunk/jenga/projects/smoothie/smoothie.vcproj
===================================================================
--- trunk/jenga/projects/smoothie/smoothie.vcproj	(revision 173)
+++ trunk/jenga/projects/smoothie/smoothie.vcproj	(revision 174)
@@ -277,4 +277,8 @@
 			</File>
 			<File
+				RelativePath="..\..\src\smoothie\LexicalScoping.cpp"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\smoothie\Method.cpp"
 				>
@@ -335,4 +339,8 @@
 			</File>
 			<File
+				RelativePath="..\..\include\smoothie\LexicalScoping.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\include\smoothie\Member.h"
 				>
Index: trunk/jenga/src/smoothie/LexicalScoping.cpp
===================================================================
--- trunk/jenga/src/smoothie/LexicalScoping.cpp	(revision 174)
+++ trunk/jenga/src/smoothie/LexicalScoping.cpp	(revision 174)
@@ -0,0 +1,96 @@
+#include <jenga/include/smoothie/LexicalScoping.h>
+#include <jenga/include/smoothie/SmoothieException.h>
+#include <jenga/include/smoothie/Variable.h>
+#include <jenga/include/smoothie/Procedure.h>
+
+
+CScope::CScope( int level, int addr, SCOPE_TYPE TypeOfStatement ){
+	this->level = level;
+	this->StartAddress = addr;
+	this->TypeOfStatement = TypeOfStatement;
+
+	pBreakSchedule = (DWORD *)malloc( 1 );
+	nBreakSchedule = 0;
+}
+CScope::~CScope(){
+	free( pBreakSchedule );
+}
+
+int CScope::GetStartAddress(){
+	return StartAddress;
+}
+SCOPE_TYPE CScope::GetTypeOfStatement(){
+	return TypeOfStatement;
+}
+
+
+
+
+CScope *CLexicalScopes::SearchScope( SCOPE_TYPE TypeOfStatement ){
+	for( int i = level; i>=0; i-- ){
+		if( ppScopes[i]->GetTypeOfStatement() == TypeOfStatement ){
+			return ppScopes[i];
+		}
+	}
+	return NULL;
+}
+
+CLexicalScopes::CLexicalScopes(){
+	ppScopes = (CScope **)malloc( 1 );
+	level=0;
+}
+CLexicalScopes::~CLexicalScopes(){
+	free( ppScopes );
+}
+void CLexicalScopes::Init(int addr){
+	// TODO: エラーチェック
+
+	level = -1;
+	Start( addr, SCOPE_TYPE_BASE );
+}
+void CLexicalScopes::Start( int addr, SCOPE_TYPE TypeOfStatement ){
+	level++;
+	ppScopes = (CScope **)realloc( ppScopes, ( level + 1 ) * sizeof( CScope * ) );
+	ppScopes[level] = CreateScope( level, addr, TypeOfStatement );
+}
+void CLexicalScopes::End(){
+	if( level <= 0 ){
+		throw SmoothieException();
+		return;
+	}
+
+	//デストラクタを呼ぶ
+	CallDestructorsOfScopeEnd();
+
+	Variables &vars = UserProc::IsGlobalAreaCompiling()?
+		globalVars :
+		UserProc::CompilingUserProc().localVars;
+
+	//使用済みローカル変数の生存チェックを外す
+	BOOST_FOREACH( Variable *pVar, vars ){
+		if(pVar->bLiving&&pVar->ScopeLevel==level){
+			pVar->bLiving=0;
+			extern int obp;
+			pVar->ScopeEndAddress=obp;
+		}
+	}
+
+
+	//スコープ抜け出しスケジュール
+	ppScopes[level]->RunScheduleOfBreak();
+
+
+	//スコープレベルを下げる
+	delete ppScopes[level];
+	level--;
+}
+
+int CLexicalScopes::GetNowLevel(){
+	return level;
+}
+void CLexicalScopes::SetNowLevel( int level ){
+	this->level = level;
+}
+int CLexicalScopes::GetStartAddress(){
+	return ppScopes[level]->GetStartAddress();
+}
Index: trunk/jenga/src/smoothie/Smoothie.cpp
===================================================================
--- trunk/jenga/src/smoothie/Smoothie.cpp	(revision 173)
+++ trunk/jenga/src/smoothie/Smoothie.cpp	(revision 174)
@@ -7,4 +7,5 @@
 NamespaceScopesCollection Smoothie::Temp::importedNamespaces;
 const CClass *Smoothie::Temp::pCompilingClass = NULL;
+CLexicalScopes *Smoothie::Temp::pLexicalScopes = NULL;
 
 bool Smoothie::isFullCompile = false;
Index: trunk/jenga/src/smoothie/Variable.cpp
===================================================================
--- trunk/jenga/src/smoothie/Variable.cpp	(revision 173)
+++ trunk/jenga/src/smoothie/Variable.cpp	(revision 174)
@@ -1,2 +1,3 @@
+#include <jenga/include/smoothie/Smoothie.h>
 #include <jenga/include/smoothie/Class.h>
 
@@ -28,5 +29,5 @@
 		Variable &var = *(*this)[i];
 		if( var.bLiving											//現在のスコープで有効なもの
-			&& var.ScopeLevel == obj_LexScopes.GetNowLevel()	//現在のスコープと同一レベル
+			&& var.ScopeLevel == Smoothie::Temp::pLexicalScopes->GetNowLevel()	//現在のスコープと同一レベル
 			){
 				if( var.IsEqualSymbol( symbol ) ){
@@ -38,5 +39,5 @@
 }
 
-const Variables::Variable *BackSearch( const Symbol &symbol ) const
+const Variable *Variables::BackSearch( const Symbol &symbol ) const
 {
 	//レキシカルスコープを考慮してバックサーチ
@@ -44,5 +45,5 @@
 		Variable &var = *(*this)[i];
 		if( var.bLiving											//現在のスコープで有効なもの
-			&& var.ScopeLevel <= obj_LexScopes.GetNowLevel()	//現在のスコープレベルを超さないもの（Returnによる解放処理中を考慮）
+			&& var.ScopeLevel <= Smoothie::Temp::pLexicalScopes->GetNowLevel()	//現在のスコープレベルを超さないもの（Returnによる解放処理中を考慮）
 			){
 				if( var.IsEqualSymbol( symbol ) ){
@@ -54,5 +55,5 @@
 }
 
-const Variables::Variable *Find( const Symbol &symbol )const
+const Variable *Variables::Find( const Symbol &symbol )const
 {
 	int max = (int)this->size();
