Merge branch 'gh/maint-clean' into ht/-include
[shapes.git] / source / coreast.cc
blob16761833a0e1d5ced5b78edd3f6e878514e70b10
1 /* This file is part of Shapes.
3 * Shapes is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * any later version.
8 * Shapes is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright 2008 Henrik Tidefelt
19 #include <cmath>
21 #include "Shapes_Helpers_decls.h"
23 #include "shapescore.h"
24 #include "continuations.h"
25 #include "globals.h"
26 #include "texlabelmanager.h"
27 #include "shapesexceptions.h"
29 using namespace Shapes;
32 namespace Shapes
34 namespace Lang
37 class Core_TeX : public Lang::CoreFunction
39 public:
40 Core_TeX( const char * title )
41 : CoreFunction( title )
42 { }
43 virtual void
44 call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const
46 const size_t ARITY = 1;
47 CHECK_ARITY( args, ARITY, title_ );
49 typedef const Lang::String ArgType;
50 RefCountPtr< ArgType > arg = Helpers::down_cast_CoreArgument< ArgType >( title_, args, 0, callLoc );
52 Kernel::ContRef cont = evalState->cont_;
53 cont->takeValue( Kernel::theTeXLabelManager.request( std::string( arg->val_.getPtr( ) ), args.getLoc( 0 ), evalState->dyn_ ),
54 evalState );
58 class Core_coords2D : public Lang::CoreFunction
60 public:
61 Core_coords2D( const char * title )
62 : CoreFunction( title )
63 { }
64 virtual void
65 call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const
67 const size_t ARITY = 2;
68 CHECK_ARITY( args, ARITY, title_ );
70 RefCountPtr< const Lang::Value > xUntyped = args.getValue( 0 );
71 RefCountPtr< const Lang::Value > yUntyped = args.getValue( 1 );
74 typedef const Lang::Float ArgType;
75 ArgType * xVal = dynamic_cast< ArgType * >( xUntyped.getPtr( ) );
76 if( xVal != 0 )
78 ArgType * yVal = dynamic_cast< ArgType * >( yUntyped.getPtr( ) );
79 if( yVal == 0 )
81 if( xVal->val_ == 0 )
83 /* This is a special case, where 0 is interpreted as a length.
85 typedef const Lang::Length ArgTypeY;
86 ArgTypeY * yVal = dynamic_cast< ArgTypeY * >( yUntyped.getPtr( ) );
87 if( yVal != 0 )
89 Kernel::ContRef cont = evalState->cont_;
90 cont->takeValue( Kernel::ValueRef( new Lang::Coords2D( Lang::Length( 0 ), *yVal ) ),
91 evalState );
92 return;
95 throw Exceptions::CoreTypeMismatch( callLoc, "(<>, y )", args, 1, ArgType::staticTypeName( ) );
98 Kernel::ContRef cont = evalState->cont_;
99 cont->takeValue( Kernel::ValueRef( new Lang::FloatPair( xVal->val_, yVal->val_ ) ),
100 evalState );
101 return;
106 typedef const Lang::Length ArgType;
107 ArgType * xVal = dynamic_cast< ArgType * >( xUntyped.getPtr( ) );
108 if( xVal != 0 )
110 ArgType * yVal = dynamic_cast< ArgType * >( yUntyped.getPtr( ) );
111 if( yVal == 0 )
113 /* A Float with value 0 is still allowed
115 typedef const Lang::Float ArgTypeY;
116 ArgTypeY * yVal = dynamic_cast< ArgTypeY * >( yUntyped.getPtr( ) );
117 if( yVal != 0 )
119 if( yVal->val_ == 0 )
121 Kernel::ContRef cont = evalState->cont_;
122 cont->takeValue( Kernel::ValueRef( new Lang::Coords2D( *xVal, Lang::Length( 0 ) ) ),
123 evalState );
124 return;
127 throw Exceptions::CoreTypeMismatch( callLoc, "(<>, y )", args, 1, ArgType::staticTypeName( ) );
130 Kernel::ContRef cont = evalState->cont_;
131 cont->takeValue( Kernel::ValueRef( new Lang::Coords2D( *xVal, *yVal ) ),
132 evalState );
133 return;
137 throw Exceptions::CoreTypeMismatch( callLoc, "( x ,<>)", args, 0, Helpers::typeSetString( Lang::Float::staticTypeName( ), Lang::Length::staticTypeName( ) ) );
141 class Core_cornercoords2D : public Lang::CoreFunction
143 public:
144 Core_cornercoords2D( const char * title )
145 : CoreFunction( title )
147 virtual void
148 call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const
151 * We don't check for presence of named arguments here since this function is generally called internally, and
152 * we don't want the extra overhead of an unnecessary check.
155 Kernel::ContRef cont = evalState->cont_;
156 switch( args.size( ) )
158 case 2:
159 cont->takeValue( Kernel::ValueRef( new Lang::CornerCoords2D( * Helpers::down_cast_CoreArgument< const Lang::Length >( "( x, <> ^ )", args, 0, callLoc ),
160 * Helpers::down_cast_CoreArgument< const Lang::Length >( "( <>, y ^ )", args, 1, callLoc ),
161 std::numeric_limits< double >::signaling_NaN( ) ) ),
162 evalState );
163 break;
164 case 3:
165 cont->takeValue( Kernel::ValueRef( new Lang::CornerCoords2D( * Helpers::down_cast_CoreArgument< const Lang::Length >( "( x, <> ^ <> )", args, 0, callLoc ),
166 * Helpers::down_cast_CoreArgument< const Lang::Length >( "( <>, y ^ <> )", args, 1, callLoc ),
167 Helpers::down_cast_CoreArgument< const Lang::Float >( "( <>, <> ^ a )", args, 2, callLoc )->val_ ) ),
168 evalState );
169 break;
170 default:
171 throw Exceptions::CoreArityMismatch( title_, 2, 3, args.size( ) );
177 class Core_coords3D : public Lang::CoreFunction
179 public:
180 Core_coords3D( const char * title )
181 : CoreFunction( title )
183 virtual void
184 call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const
186 const size_t ARITY = 3;
187 CHECK_ARITY( args, ARITY, title_ );
189 RefCountPtr< const Lang::Value > xUntyped = args.getValue( 0 );
190 RefCountPtr< const Lang::Value > yUntyped = args.getValue( 1 );
191 RefCountPtr< const Lang::Value > zUntyped = args.getValue( 2 );
194 typedef const Lang::Float ArgType;
195 ArgType * xVal = dynamic_cast< ArgType * >( xUntyped.getPtr( ) );
196 if( xVal != 0 )
198 Kernel::ContRef cont = evalState->cont_;
199 cont->takeValue( Kernel::ValueRef( new Lang::FloatTriple( xVal->val_,
200 Helpers::down_cast_CoreArgument< ArgType >( "(<>, y ,<>)", args, 1, callLoc )->val_,
201 Helpers::down_cast_CoreArgument< ArgType >( "(<>,<>, z )", args, 2, callLoc )->val_ ) ),
202 evalState );
203 return;
208 typedef const Lang::Length ArgType;
209 ArgType * xVal = dynamic_cast< ArgType * >( xUntyped.getPtr( ) );
210 if( xVal != 0 )
212 Kernel::ContRef cont = evalState->cont_;
213 cont->takeValue( Kernel::ValueRef( new Lang::Coords3D( *xVal,
214 * Helpers::down_cast_CoreArgument< ArgType >( "(<>, y ,<>)", args, 1, callLoc ),
215 * Helpers::down_cast_CoreArgument< ArgType >( "(<>,<>, z )", args, 2, callLoc ) ) ),
216 evalState );
217 return;
221 throw Exceptions::CoreTypeMismatch( callLoc, "( x ,<>,<>)", args, 0, Helpers::typeSetString( Lang::Float::staticTypeName( ), Lang::Length::staticTypeName( ) ) );
225 class Core_polarHandle2DFree_r : public Lang::CoreFunction
227 public:
228 Core_polarHandle2DFree_r( const char * title )
229 : CoreFunction( title )
231 virtual void
232 call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const
234 const size_t ARITY = 1;
235 CHECK_ARITY( args, ARITY, title_ );
237 Kernel::ContRef cont = evalState->cont_;
238 cont->takeValue( Kernel::ValueRef( new Lang::PolarHandle2DFree_r( evalState->dyn_->getDefaultUnit( ),
239 Helpers::down_cast_CoreArgument< const Lang::Float >( "(^ a )", args, 0, callLoc )->val_ ) ),
240 evalState );
244 class Core_polarHandle2DFree_ra : public Lang::CoreFunction
246 public:
247 Core_polarHandle2DFree_ra( const char * title )
248 : CoreFunction( title )
250 virtual void
251 call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const
253 const size_t ARITY = 0;
254 CHECK_ARITY( args, ARITY, title_ );
256 Kernel::ContRef cont = evalState->cont_;
257 cont->takeValue( Kernel::ValueRef( new Lang::PolarHandle2DFree_ra( evalState->dyn_->getDefaultUnit( ) ) ),
258 evalState );
267 RefCountPtr< const Lang::CoreFunction > Ast::THE_FUNCTION_coords2D( new Lang::Core_coords2D( "coords" ) );
268 RefCountPtr< const Lang::CoreFunction > Ast::THE_FUNCTION_cornercoords2D( new Lang::Core_cornercoords2D( "cornercoords" ) );
269 RefCountPtr< const Lang::CoreFunction > Ast::THE_FUNCTION_coords3D( new Lang::Core_coords3D( "coords3D" ) );
270 RefCountPtr< const Lang::CoreFunction > Ast::THE_FUNCTION_polarHandle2DFree_r( new Lang::Core_polarHandle2DFree_r( "polarHandleFree_r" ) );
271 RefCountPtr< const Lang::CoreFunction > Ast::THE_FUNCTION_polarHandle2DFree_ra( new Lang::Core_polarHandle2DFree_ra( "polarHandleFree_ra" ) );
272 /* This belongs in consts.cc but we must make sure it is initialized before we use it below. Note that the identifier will actually be destroyed
273 * before Ast::THE_FUNCTION_TeX is destroyed, but that should not cause a failure...
275 const char * Lang::TEX_SYNTAX_ID = "TeX";
276 RefCountPtr< const Lang::CoreFunction > Ast::THE_FUNCTION_TeX( new Lang::Core_TeX( Lang::TEX_SYNTAX_ID ) );