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
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
21 #include "Shapes_Helpers_decls.h"
23 #include "shapescore.h"
24 #include "continuations.h"
26 #include "texlabelmanager.h"
27 #include "shapesexceptions.h"
29 using namespace Shapes
;
37 class Core_TeX
: public Lang::CoreFunction
40 Core_TeX( const char * title
)
41 : CoreFunction( title
)
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_
),
58 class Core_coords2D
: public Lang::CoreFunction
61 Core_coords2D( const char * title
)
62 : CoreFunction( title
)
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( ) );
78 ArgType
* yVal
= dynamic_cast< ArgType
* >( yUntyped
.getPtr( ) );
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( ) );
89 Kernel::ContRef cont
= evalState
->cont_
;
90 cont
->takeValue( Kernel::ValueRef( new Lang::Coords2D( Lang::Length( 0 ), *yVal
) ),
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_
) ),
106 typedef const Lang::Length ArgType
;
107 ArgType
* xVal
= dynamic_cast< ArgType
* >( xUntyped
.getPtr( ) );
110 ArgType
* yVal
= dynamic_cast< ArgType
* >( yUntyped
.getPtr( ) );
113 /* A Float with value 0 is still allowed
115 typedef const Lang::Float ArgTypeY
;
116 ArgTypeY
* yVal
= dynamic_cast< ArgTypeY
* >( yUntyped
.getPtr( ) );
119 if( yVal
->val_
== 0 )
121 Kernel::ContRef cont
= evalState
->cont_
;
122 cont
->takeValue( Kernel::ValueRef( new Lang::Coords2D( *xVal
, Lang::Length( 0 ) ) ),
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
) ),
137 throw Exceptions::CoreTypeMismatch( callLoc
, "( x ,<>)", args
, 0, Helpers::typeSetString( Lang::Float::staticTypeName( ), Lang::Length::staticTypeName( ) ) );
141 class Core_cornercoords2D
: public Lang::CoreFunction
144 Core_cornercoords2D( const char * title
)
145 : CoreFunction( title
)
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( ) )
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( ) ) ),
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_
) ),
171 throw Exceptions::CoreArityMismatch( title_
, 2, 3, args
.size( ) );
177 class Core_coords3D
: public Lang::CoreFunction
180 Core_coords3D( const char * title
)
181 : CoreFunction( title
)
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( ) );
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_
) ),
208 typedef const Lang::Length ArgType
;
209 ArgType
* xVal
= dynamic_cast< ArgType
* >( xUntyped
.getPtr( ) );
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
) ) ),
221 throw Exceptions::CoreTypeMismatch( callLoc
, "( x ,<>,<>)", args
, 0, Helpers::typeSetString( Lang::Float::staticTypeName( ), Lang::Length::staticTypeName( ) ) );
225 class Core_polarHandle2DFree_r
: public Lang::CoreFunction
228 Core_polarHandle2DFree_r( const char * title
)
229 : CoreFunction( title
)
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_
) ),
244 class Core_polarHandle2DFree_ra
: public Lang::CoreFunction
247 Core_polarHandle2DFree_ra( const char * title
)
248 : CoreFunction( title
)
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( ) ) ),
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
) );