From 91f363ee0699914dba35a3ee6522437819fcfb8b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= <tseeker@nocternity.net>
Date: Mon, 13 Nov 2017 17:28:57 +0100
Subject: [PATCH] Compiler - Viewport instruction

---
 control.hh  |  1 +
 opast.cc    |  2 +-
 opast.hh    | 14 ++++++++++----
 opcomp.cc   |  6 ++++++
 opparser.cc |  2 +-
 ops.cc      |  1 +
 6 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/control.hh b/control.hh
index fbd78bf..d7250c9 100644
--- a/control.hh
+++ b/control.hh
@@ -59,6 +59,7 @@ enum E_OpType
 	OP_USE_PROGRAM ,
 	OP_USE_TEXTURE ,
 	OP_UNIFORMS ,
+	OP_VIEWPORT ,
 	//
 	OP_FULLSCREEN ,
 	OP_CLEAR ,
diff --git a/opast.cc b/opast.cc
index baf62b4..02483b5 100644
--- a/opast.cc
+++ b/opast.cc
@@ -274,7 +274,7 @@ A_Node* opast::ASTVisitorBrowser(
 		auto c = child;
 		for ( int i = 0 ; i < 4 ; i ++ ) {
 			T_ViewportInstrNode::E_Parameter p{
-				T_ViewportInstrNode::E_Parameter( i ) };
+				T_ViewportInstrNode::E_Parameter( 3 - i ) };
 			if ( n.hasParameter( p ) ) {
 				if ( c == 0 ) {
 					return &n.parameter( p );
diff --git a/opast.hh b/opast.hh
index c7d4d67..5741cde 100644
--- a/opast.hh
+++ b/opast.hh
@@ -1148,7 +1148,7 @@ class T_ViewportInstrNode : public A_InstructionNode
 	};
 
     private:
-	P_ExpressionNode parameters_[ 4 ];
+	P_ArgumentNode parameters_[ 4 ];
 
     public:
 	T_ViewportInstrNode( T_InstrListNode& parent ) noexcept
@@ -1156,11 +1156,17 @@ class T_ViewportInstrNode : public A_InstructionNode
 				E_InstrRestriction::INIT )
 	{ }
 
-	void setParameter( const E_Parameter p , P_ExpressionNode height ) noexcept
-		{ parameters_[ int( p ) ] = std::move( height ); }
+	void setParameter( const E_Parameter p , P_ExpressionNode value ) noexcept
+	{
+		if ( value ) {
+			parameters_[ int( p ) ] = NewOwned< T_ArgumentNode >(
+					*this , std::move( value ) );
+		}
+	}
+
 	bool hasParameter( const E_Parameter p ) const noexcept
 		{ return bool( parameters_[ int( p ) ] ); }
-	A_ExpressionNode& parameter( const E_Parameter p ) const noexcept
+	T_ArgumentNode& parameter( const E_Parameter p ) const noexcept
 		{ return *parameters_[ int( p ) ]; }
 };
 
diff --git a/opcomp.cc b/opcomp.cc
index a564400..1025c61 100644
--- a/opcomp.cc
+++ b/opcomp.cc
@@ -543,6 +543,12 @@ bool T_CompilerImpl_::compileNode(
 		}
 		break;
 
+	    case A_Node::OP_VIEWPORT:
+		if ( exit ) {
+			addInstruction( OP_VIEWPORT , node.location( ) );
+		}
+		break;
+
 
 	    //- RENDERING -------------------------------------------------------------------------
 
diff --git a/opparser.cc b/opparser.cc
index 88cbac0..4a71043 100644
--- a/opparser.cc
+++ b/opparser.cc
@@ -1787,7 +1787,7 @@ M_INSTR_( Viewport )
 
 	for ( auto i = 1u ; i < 5 ; i ++ ) {
 		T_ViewportInstrNode::E_Parameter p{
-			T_ViewportInstrNode::E_Parameter( i ) };
+			T_ViewportInstrNode::E_Parameter( i - 1 ) };
 		if ( input.size( ) < i ) {
 			T_StringBuilder sb;
 			sb << "missing ";
diff --git a/ops.cc b/ops.cc
index 3c602ca..8862dc3 100644
--- a/ops.cc
+++ b/ops.cc
@@ -131,6 +131,7 @@ static T_KeyValueTable< E_OpType , T_OpInfo > OpInfoTable_{ ([]() {
 	infos.add( E_OpType::OP_USE_PROGRAM , T_OpInfo{ "use-program" , 0 , OpStackMain{ -1 } } );
 	infos.add( E_OpType::OP_USE_TEXTURE , T_OpInfo{ "use-texture" , 1 , OpStackMain{ -2 } } );
 	infos.add( E_OpType::OP_UNIFORMS , T_OpInfo{ "uniforms" , 2 , OpStackMain{ -2 } } );
+	infos.add( E_OpType::OP_VIEWPORT , T_OpInfo{ "viewport" , 0 , OpStackMain{ -4 } } );
 	//
 	infos.add( E_OpType::OP_FULLSCREEN , T_OpInfo{ "fullscreen" } );
 	infos.add( E_OpType::OP_CLEAR , T_OpInfo{ "clear" , 0 , OpStackMain{ -4 } } );