Index: src/AST/Expr.cpp
===================================================================
--- src/AST/Expr.cpp	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/AST/Expr.cpp	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -307,4 +307,18 @@
 }
 
+// 
+
+// --- EnumPosExpr
+EnumPosExpr::EnumPosExpr( const CodeLocation & loc, const EnumInstType * ty)
+: Expr( loc, new BasicType{ BasicType::UnsignedInt }), type( ty ) {
+	assert( ty );
+}
+
+EnumPosExpr::EnumPosExpr( const CodeLocation & loc, const Expr * expr )
+: Expr( loc, new BasicType{ BasicType::UnsignedInt }), expr(expr) {
+	assert( expr );
+}
+
+
 // --- LogicalExpr
 
Index: src/AST/Expr.hpp
===================================================================
--- src/AST/Expr.hpp	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/AST/Expr.hpp	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -548,4 +548,17 @@
 };
 
+class EnumPosExpr final : public Expr {
+public:
+	ptr<EnumInstType> type;
+	ptr<Expr> expr;
+	
+	EnumPosExpr( const CodeLocation & loc, const EnumInstType * ty );
+	EnumPosExpr( const CodeLocation & loc, const Expr * expr );
+	const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
+private:
+	EnumPosExpr * clone() const override { return new EnumPosExpr{ *this }; }
+	MUTATE_FRIEND
+};
+
 /// Variants of short-circuiting logical expression
 enum LogicalFlag { OrExpr, AndExpr };
Index: src/AST/Fwd.hpp
===================================================================
--- src/AST/Fwd.hpp	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/AST/Fwd.hpp	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -89,4 +89,5 @@
 class OffsetofExpr;
 class OffsetPackExpr;
+class EnumPosExpr;
 class LogicalExpr;
 class ConditionalExpr;
Index: src/AST/Node.cpp
===================================================================
--- src/AST/Node.cpp	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/AST/Node.cpp	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -232,4 +232,6 @@
 template class ast::ptr_base< ast::OffsetPackExpr, ast::Node::ref_type::weak >;
 template class ast::ptr_base< ast::OffsetPackExpr, ast::Node::ref_type::strong >;
+template class ast::ptr_base< ast::EnumPosExpr, ast::Node::ref_type::weak >;
+template class ast::ptr_base< ast::EnumPosExpr, ast::Node::ref_type::strong >;
 template class ast::ptr_base< ast::LogicalExpr, ast::Node::ref_type::weak >;
 template class ast::ptr_base< ast::LogicalExpr, ast::Node::ref_type::strong >;
Index: src/AST/Pass.hpp
===================================================================
--- src/AST/Pass.hpp	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/AST/Pass.hpp	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -191,4 +191,5 @@
 	const ast::Expr *             visit( const ast::OffsetofExpr         * ) override final;
 	const ast::Expr *             visit( const ast::OffsetPackExpr       * ) override final;
+	const ast::Expr *             visit( const ast::EnumPosExpr          * ) override final;
 	const ast::Expr *             visit( const ast::LogicalExpr          * ) override final;
 	const ast::Expr *             visit( const ast::ConditionalExpr      * ) override final;
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/AST/Pass.impl.hpp	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -1452,4 +1452,19 @@
 
 //--------------------------------------------------------------------------
+// EnumPosExpr
+template< typename core_t>
+const ast::Expr * ast::Pass< core_t >::visit( const ast::EnumPosExpr * node ) {
+	VISIT_START( node );
+
+	if ( __visit_children() ) {
+		guard_symtab guard { *this };
+		maybe_accept( node, &EnumPosExpr::type );
+		maybe_accept( node, &EnumPosExpr::expr );
+	}
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
 // LogicalExpr
 template< typename core_t >
Index: src/AST/Print.cpp
===================================================================
--- src/AST/Print.cpp	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/AST/Print.cpp	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -1183,4 +1183,13 @@
 	}
 
+	virtual const ast::Expr * visit( const ast::EnumPosExpr * node ) override final {
+		os << "Enum Position Expression on: ";
+		++indent;
+		safe_print( node->type );
+		--indent;
+		postprint( node );
+		return node;
+	}
+
 	virtual const ast::Expr * visit( const ast::LogicalExpr * node ) override final {
 		os << "Short-circuited operation (" << (node->isAnd ? "and" : "or") << ") on: ";
Index: src/AST/Visitor.hpp
===================================================================
--- src/AST/Visitor.hpp	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/AST/Visitor.hpp	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -79,4 +79,5 @@
     virtual const ast::Expr *             visit( const ast::OffsetofExpr         * ) = 0;
     virtual const ast::Expr *             visit( const ast::OffsetPackExpr       * ) = 0;
+    virtual const ast::Expr *             visit( const ast::EnumPosExpr          * ) = 0;
     virtual const ast::Expr *             visit( const ast::LogicalExpr          * ) = 0;
     virtual const ast::Expr *             visit( const ast::ConditionalExpr      * ) = 0;
Index: src/CodeGen/CodeGenerator.cpp
===================================================================
--- src/CodeGen/CodeGenerator.cpp	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/CodeGen/CodeGenerator.cpp	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -778,4 +778,9 @@
 }
 
+void CodeGenerator::postvisit( ast::EnumPosExpr const * expr ) {
+	assertf( !options.genC, "EnumPosExpr should not reach code generation." );
+	output << "__CFA_enumeration_pos(" << genType( expr->type, "", options ) << ")";
+}
+
 void CodeGenerator::postvisit( ast::LogicalExpr const * expr ) {
 	extension( expr );
Index: src/CodeGen/CodeGenerator.hpp
===================================================================
--- src/CodeGen/CodeGenerator.hpp	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/CodeGen/CodeGenerator.hpp	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -76,4 +76,5 @@
 	void postvisit( ast::OffsetPackExpr const * );
 	void postvisit( ast::LogicalExpr const * );
+	void postvisit( ast::EnumPosExpr const * );
 	void postvisit( ast::ConditionalExpr const * );
 	void postvisit( ast::CommaExpr const * );
Index: src/Common/CodeLocationTools.cpp
===================================================================
--- src/Common/CodeLocationTools.cpp	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/Common/CodeLocationTools.cpp	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -158,4 +158,5 @@
     macro(OffsetPackExpr, Expr) \
     macro(LogicalExpr, Expr) \
+	macro(EnumPosExpr, Expr) \
     macro(ConditionalExpr, Expr) \
     macro(CommaExpr, Expr) \
Index: src/GenPoly/Box.cpp
===================================================================
--- src/GenPoly/Box.cpp	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/GenPoly/Box.cpp	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -1580,4 +1580,6 @@
 	ast::Expr const * postvisit( ast::OffsetPackExpr const * expr );
 
+	ast::Expr const * postvisit( ast::EnumPosExpr const * expr );
+
 	void beginScope();
 	void endScope();
@@ -1950,4 +1952,9 @@
 
 	return new ast::VariableExpr( expr->location, offsetArray );
+}
+
+// TODO 
+ast::Expr const * PolyGenericCalculator::postvisit( ast::EnumPosExpr const * expr ) {
+	return expr;
 }
 
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/InitTweak/InitTweak.cc	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -271,4 +271,5 @@
 		void previsit( const ast::OffsetofExpr * ) {}
 		void previsit( const ast::OffsetPackExpr * ) {}
+		void previsit( const ast::EnumPosExpr * ) {}
 		void previsit( const ast::CommaExpr * ) {}
 		void previsit( const ast::LogicalExpr * ) {}
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/Parser/ExpressionNode.cc	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -690,4 +690,9 @@
 } // build_unary_val
 
+ast::Expr * build_enum_pos_expr( const CodeLocation & location, ast::Expr * expr_node ) {
+	// return nullptr
+	return new ast::EnumPosExpr( location, std::move( expr_node ) );
+}
+
 ast::Expr * build_binary_val( const CodeLocation & location,
 		OperKinds op,
Index: src/Parser/ExpressionNode.h
===================================================================
--- src/Parser/ExpressionNode.h	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/Parser/ExpressionNode.h	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -83,2 +83,4 @@
 ast::Expr * build_func( const CodeLocation &, ExpressionNode * function, ExpressionNode * expr_node );
 ast::Expr * build_compoundLiteral( const CodeLocation &, DeclarationNode * decl_node, InitializerNode * kids );
+
+ast::Expr * build_enum_pos_expr( const CodeLocation &, ast::Expr * expr_node );
Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -52,4 +52,6 @@
 #include "Common/Stats/Counter.h"
 
+#include "AST/Inspect.hpp"             // for getFunctionName
+
 #define PRINT( text ) if ( resolvep ) { text }
 
@@ -656,4 +658,5 @@
 		void postvisit( const ast::OffsetofExpr * offsetofExpr );
 		void postvisit( const ast::OffsetPackExpr * offsetPackExpr );
+		void postvisit( const ast::EnumPosExpr * enumPosExpr );
 		void postvisit( const ast::LogicalExpr * logicalExpr );
 		void postvisit( const ast::ConditionalExpr * conditionalExpr );
@@ -1471,4 +1474,28 @@
 	void Finder::postvisit( const ast::OffsetPackExpr * offsetPackExpr ) {
 		addCandidate( offsetPackExpr, tenv );
+	}
+
+	void Finder::postvisit( const ast::EnumPosExpr * enumPosExpr ) {
+		CandidateFinder finder( context, tenv );
+		finder.find( enumPosExpr->expr );
+		CandidateList winners = findMinCost( finder.candidates );
+		if ( winners.size() != 1 ) SemanticError( enumPosExpr->expr.get(), "Ambiguous expression in position. ");
+		CandidateRef & choice = winners.front();
+		auto refExpr = referenceToRvalueConversion( choice->expr, choice->cost );
+		auto refResult = (refExpr->result).as<ast::EnumInstType>();
+		if ( !refResult ) {
+			SemanticError( refExpr, "Position for Non enum type is not supported" );
+		}
+		// determineEnumPosConstant( enumPosExpr, refResult );
+
+		const ast::NameExpr * const nameExpr = enumPosExpr->expr.strict_as<ast::NameExpr>();
+		const ast::EnumDecl * base = refResult->base;
+		if ( !base ) {
+			SemanticError( enumPosExpr, "Cannot be reference to a defined enumeration type" );
+		}
+		auto it = std::find_if( std::begin( base->members ), std::end( base->members ), 
+			[nameExpr]( ast::ptr<ast::Decl> decl ) { return decl->name == nameExpr->name; } );
+		unsigned position = it - base->members.begin();
+		addCandidate( ast::ConstantExpr::from_int( enumPosExpr->location, position ), tenv );
 	}
 
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/ResolvExpr/Resolver.cc	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -420,4 +420,6 @@
 		const ast::ConstructorInit * previsit( const ast::ConstructorInit * );
 
+		const ast::EnumPosExpr *	 previsit( const ast::EnumPosExpr * );
+
 		void resolveWithExprs(std::vector<ast::ptr<ast::Expr>> & exprs, std::list<ast::ptr<ast::Stmt>> & stmtsToAdd);
 
@@ -1239,4 +1241,9 @@
 	}
 
+	const ast::EnumPosExpr * Resolver::previsit( const ast::EnumPosExpr * enumPos ) {
+		visitor->maybe_accept( enumPos, &ast::EnumPosExpr::expr );
+		return enumPos;
+	}
+
 	// suppress error on autogen functions and mark invalid autogen as deleted.
 	bool Resolver::on_error(ast::ptr<ast::Decl> & decl) {
Index: src/Validate/Autogen.cpp
===================================================================
--- src/Validate/Autogen.cpp	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/Validate/Autogen.cpp	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -186,7 +186,12 @@
 		// could possibly use a new linkage type. For now we just make the
 		// basic ones intrinsic to code-gen them as C assignments.
-		const auto & real_type = decl->base;
-		const auto & basic = real_type.as<ast::BasicType>();
-		if(!real_type || (basic && basic->isInteger())) proto_linkage = ast::Linkage::Intrinsic;
+		// const auto & real_type = decl->base;
+		// const auto & basic = real_type.as<ast::BasicType>();
+
+		// if(!real_type || (basic && basic->isInteger())) proto_linkage = ast::Linkage::Intrinsic;
+
+		// Turns other enumeration type into Intrinstic as well to temporarily fix the recursive 
+		// construction bug
+		proto_linkage = ast::Linkage::Intrinsic;
 	}
 
@@ -742,4 +747,8 @@
 			}
 		);
+		// auto fname = ast::getFunctionName( callExpr );
+		// if (fname == "posE" ) {
+		// 	std::cerr << "Found posE autogen" << std::endl;
+		// }
 		functionDecl->stmts = new ast::CompoundStmt( location,
 			{ new ast::ExprStmt( location, callExpr ) }
@@ -792,8 +801,60 @@
 }
 
+struct PseudoFuncGenerateRoutine final :
+		public ast::WithDeclsToAdd<>,
+		public ast::WithShortCircuiting {
+	void previsit( const ast::EnumDecl * enumDecl );
+};
+
+void PseudoFuncGenerateRoutine::previsit( const ast::EnumDecl * enumDecl ) {
+	const CodeLocation& location = enumDecl->location;
+	if ( enumDecl->members.size() == 0 || !enumDecl->base || enumDecl->name == "" ) return;
+
+	std::vector<ast::ptr<ast::Init>> inits;
+	std::vector<ast::ptr<ast::Init>> labels;
+	for ( const ast::Decl * mem: enumDecl->members ) {
+		auto memAsObjectDecl = dynamic_cast< const ast::ObjectDecl * >( mem );
+		inits.emplace_back( memAsObjectDecl->init );
+		labels.emplace_back( new ast::SingleInit( 
+			location, ast::ConstantExpr::from_string(location, mem->name) ) );
+	}
+	auto init = new ast::ListInit( location, std::move( inits ) );
+	auto label_strings = new ast::ListInit( location, std::move(labels) );
+	auto values = new ast::ObjectDecl( 
+		location,
+		"__enum_values_"+enumDecl->name,
+		new ast::ArrayType(
+			// new ast::PointerType( new ast::BasicType{ ast::BasicType::Char} ),
+			enumDecl->base,
+			ast::ConstantExpr::from_int( location, enumDecl->members.size() ), 
+			ast::LengthFlag::FixedLen, ast::DimensionFlag::DynamicDim
+		)
+		,init
+		,
+		ast::Storage::Static,
+		ast::Linkage::AutoGen
+	);
+	auto label_arr = new ast::ObjectDecl(
+		location,
+		"__enum_labels_"+enumDecl->name,
+		new ast::ArrayType(
+			new ast::PointerType( new ast::BasicType{ ast::BasicType::Char} ),
+			ast::ConstantExpr::from_int( location, enumDecl->members.size() ), 
+			ast::LengthFlag::FixedLen, ast::DimensionFlag::DynamicDim
+		),
+		label_strings,
+		ast::Storage::Static,
+		ast::Linkage::AutoGen
+	);
+
+	declsToAddAfter.push_back( values );
+	declsToAddAfter.push_back( label_arr );
+}
+
 } // namespace
 
 void autogenerateRoutines( ast::TranslationUnit & translationUnit ) {
 	ast::Pass<AutogenerateRoutines>::run( translationUnit );
+	// ast::Pass<PseudoFuncGenerateRoutine>::run( translationUnit );
 }
 
Index: src/Validate/module.mk
===================================================================
--- src/Validate/module.mk	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/Validate/module.mk	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -52,5 +52,7 @@
 	Validate/ReturnCheck.hpp \
 	Validate/VerifyCtorDtorAssign.cpp \
-	Validate/VerifyCtorDtorAssign.hpp
+	Validate/VerifyCtorDtorAssign.hpp \
+	Validate/ReplacePseudoFunc.cpp \
+	Validate/ReplacePseudoFunc.hpp
 
 SRCDEMANGLE += $(SRC_VALIDATE)
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/main.cc	(revision 59c8dff49bbb5284b39ab27da894a644327a531a)
@@ -82,4 +82,5 @@
 #include "Validate/ReturnCheck.hpp"         // for checkReturnStatements
 #include "Validate/VerifyCtorDtorAssign.hpp" // for verifyCtorDtorAssign
+#include "Validate/ReplacePseudoFunc.hpp"
 #include "Virtual/ExpandCasts.h"            // for expandCasts
 #include "Virtual/VirtualDtor.hpp"          // for implementVirtDtors
@@ -287,5 +288,4 @@
 			assertf( extras, "cannot open extras.cf\n" );
 			parse( extras, ast::Linkage::BuiltinC );
-
 			if ( ! libcfap ) {
 				// read the prelude in, if not generating the cfa library
@@ -322,4 +322,5 @@
 		PASS( "Forall Pointer Decay", Validate::decayForallPointers, transUnit );
 		PASS( "Fix Qualified Types", Validate::fixQualifiedTypes, transUnit );
+
 		PASS( "Eliminate Typedef", Validate::eliminateTypedef, transUnit );
 		PASS( "Hoist Struct", Validate::hoistStruct, transUnit );
@@ -381,4 +382,5 @@
 		PASS( "Resolve", ResolvExpr::resolve, transUnit );
 		DUMP( exprp, std::move( transUnit ) );
+		PASS( "Replace Pseudo Func", Validate::replacePseudoFunc, transUnit );
 
 		PASS( "Fix Init", InitTweak::fix, transUnit, buildingLibrary() );
