2023-01-20 18:52:57 +01:00
package io.gitlab.jfronny.muscript.ast.dynamic ;
2022-06-03 19:54:31 +02:00
2023-01-20 18:52:57 +01:00
import io.gitlab.jfronny.muscript.ast.DynamicExpr ;
import io.gitlab.jfronny.muscript.ast.Expr ;
import io.gitlab.jfronny.muscript.annotations.CanThrow ;
import io.gitlab.jfronny.muscript.annotations.UncheckedDynamic ;
2023-03-12 15:28:44 +01:00
import io.gitlab.jfronny.muscript.ast.literal.StringLiteral ;
import io.gitlab.jfronny.muscript.compiler.* ;
2023-01-20 21:05:04 +01:00
import io.gitlab.jfronny.muscript.data.Scope ;
2023-01-20 18:52:57 +01:00
import io.gitlab.jfronny.muscript.data.dynamic.* ;
2023-06-27 16:22:00 +02:00
import io.gitlab.jfronny.muscript.error.LocationalException ;
2022-06-29 15:41:44 +02:00
import io.gitlab.jfronny.muscript.error.TypeMismatchException ;
2022-06-03 19:54:31 +02:00
2023-03-12 15:28:44 +01:00
import java.io.IOException ;
2022-06-29 15:41:44 +02:00
@CanThrow
@UncheckedDynamic
2022-06-07 13:36:48 +02:00
public class Get extends DynamicExpr {
2022-06-07 12:19:58 +02:00
private final DynamicExpr left ;
2022-06-03 19:54:31 +02:00
private final Expr < ? > name ;
2023-04-18 13:40:34 +02:00
public Get ( CodeLocation location , DynamicExpr left , Expr < ? > name ) {
super ( Order . Call , location ) ;
2022-06-03 19:54:31 +02:00
this . left = left ;
this . name = name ;
2022-06-07 12:19:58 +02:00
if ( name . getResultType ( ) ! = Type . String & & name . getResultType ( ) ! = Type . Number & & name . getResultType ( ) ! = Type . Dynamic ) {
2023-04-18 13:40:34 +02:00
throw new TypeMismatchException ( location , Type . String , name . getResultType ( ) , " Name must be either a string or a number " ) ;
2022-06-03 19:54:31 +02:00
}
}
@Override
2023-01-20 21:05:04 +01:00
public Dynamic < ? > get ( Scope dataRoot ) {
2022-06-13 13:31:54 +02:00
Dynamic < ? > left = this . left . get ( dataRoot ) ;
2023-06-27 16:22:00 +02:00
if ( left = = null | | left instanceof DNull ) throw new LocationalException ( location , " Could not get \" " + name . asStringExpr ( ) . get ( dataRoot ) + " \" because left is null " ) ;
2022-06-07 12:19:58 +02:00
if ( left instanceof DObject o ) {
2022-06-13 13:31:54 +02:00
return o . get ( name . asStringExpr ( ) . get ( dataRoot ) ) ;
2022-06-07 12:19:58 +02:00
} else if ( left instanceof DList l ) {
2022-06-13 13:31:54 +02:00
return l . get ( name . asNumberExpr ( ) . get ( dataRoot ) . intValue ( ) ) ;
2022-06-03 19:54:31 +02:00
}
2023-04-18 13:40:34 +02:00
throw new DynamicTypeConversionException ( " object or list " , left ) . locational ( location ) ;
2022-06-03 19:54:31 +02:00
}
2022-06-29 17:38:05 +02:00
@Override
public DynamicExpr optimize ( ) {
DynamicExpr left = this . left . optimize ( ) ;
Expr < ? > name = this . name . optimize ( ) ;
2023-04-18 13:40:34 +02:00
return new Get ( location , left , name ) ;
2022-06-29 17:38:05 +02:00
}
2023-03-12 15:28:44 +01:00
@Override
public void decompile ( ExprWriter writer ) throws IOException {
parenthesize ( left , writer , false ) ;
if ( name instanceof StringLiteral lit & & Lexer . isValidId ( lit . value ) ) {
writer . append ( '.' ) . append ( lit . value ) ;
} else {
writer . append ( '[' ) ;
name . decompile ( writer ) ;
writer . append ( ']' ) ;
}
}
2022-06-29 17:38:05 +02:00
@Override
public boolean equals ( Object obj ) {
return obj instanceof Get get & & left . equals ( get . left ) & & name . equals ( get . name ) ;
}
2022-06-03 19:54:31 +02:00
}